diff --git a/ChangeLog b/ChangeLog
index 2ba2d52a199b759efe1a1a9ae86f9ab52f389e48_Q2hhbmdlTG9n..633bc556eed679d8b110123258f2cedb2a0c1246_Q2hhbmdlTG9n 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Fri Jan 19 13:16:57 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* libxslt/xslt.c: check version on stylesheets
+	* libxslt/xslt.c libxslt/xsltInternals.h libxslt/variables[.ch]:
+	  started adding variables interfaces and modules.
+
 Thu Jan 18 16:08:38 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
 	* libxslt/xslt.c: added support for disable-output-escaping
diff --git a/TODO b/TODO
index 2ba2d52a199b759efe1a1a9ae86f9ab52f389e48_VE9ETw==..633bc556eed679d8b110123258f2cedb2a0c1246_VE9ETw== 100644
--- a/TODO
+++ b/TODO
@@ -40,3 +40,8 @@
   -> add lang and case-order
   -> add foreign sorting functions (interfaces ?).
 
+Validity:
+  -> should we add validation by default ? Make this an option
+  -> redirrect validity errors
+
+
diff --git a/libxslt/Makefile.am b/libxslt/Makefile.am
index 2ba2d52a199b759efe1a1a9ae86f9ab52f389e48_bGlieHNsdC9NYWtlZmlsZS5hbQ==..633bc556eed679d8b110123258f2cedb2a0c1246_bGlieHNsdC9NYWtlZmlsZS5hbQ== 100644
--- a/libxslt/Makefile.am
+++ b/libxslt/Makefile.am
@@ -10,6 +10,8 @@
 	xsltutils.h			\
 	pattern.c			\
 	pattern.h			\
+	variables.c			\
+	variables.h			\
 	transform.c			\
 	transform.h			\
 	xsltInternals.h
diff --git a/libxslt/variables.c b/libxslt/variables.c
new file mode 100644
index 0000000000000000000000000000000000000000..633bc556eed679d8b110123258f2cedb2a0c1246_bGlieHNsdC92YXJpYWJsZXMuYw==
--- /dev/null
+++ b/libxslt/variables.c
@@ -0,0 +1,111 @@
+/*
+ * variables.c: Implementation of the variable storage and lookup
+ *
+ * Reference:
+ *   http://www.w3.org/TR/1999/REC-xslt-19991116
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel.Veillard@imag.fr
+ */
+
+#include "xsltconfig.h"
+
+#include <string.h>
+
+#include <libxml/xmlmemory.h>
+#include <libxml/tree.h>
+#include <libxml/valid.h>
+#include <libxml/hash.h>
+#include <libxml/xmlerror.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/parserInternals.h>
+#include "xslt.h"
+#include "xsltInternals.h"
+#include "xsltutils.h"
+#include "variables.h"
+
+#define DEBUG_VARIABLES
+
+/*
+ * Types are private:
+ */
+
+
+/************************************************************************
+ *									*
+ *			Module interfaces				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xsltRegisterVariable:
+ * @style:  the XSLT stylesheet
+ * @name:  the variable name
+ * @ns_uri:  the variable namespace URI
+ * @value:  the variable value or NULL
+ *
+ * Register a new variable value. If @value is NULL it unregisters
+ * the variable
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+int
+xsltRegisterVariable(xsltStylesheetPtr style, const xmlChar *name,
+		     const xmlChar *ns_uri, xmlXPathObjectPtr value) {
+    if (style == NULL)
+	return(-1);
+    if (name == NULL)
+	return(-1);
+
+    if (style->variablesHash == NULL)
+	style->variablesHash = xmlHashCreate(0);
+    if (style->variablesHash == NULL)
+	return(-1);
+    return(xmlHashUpdateEntry2((xmlHashTablePtr) style->variablesHash,
+		               name, ns_uri,
+			       (void *) value,
+			       (xmlHashDeallocator) xmlXPathFreeObject));
+}
+
+/**
+ * xsltVariableLookup:
+ * @style:  the XSLT stylesheet
+ * @name:  the variable name
+ * @ns_uri:  the variable namespace URI
+ *
+ * Search in the Variable array of the context for the given
+ * variable value.
+ *
+ * Returns the value or NULL if not found
+ */
+xmlXPathObjectPtr
+xsltVariableLookup(xsltStylesheetPtr style, const xmlChar *name,
+		   const xmlChar *ns_uri) {
+    if (style == NULL)
+	return(NULL);
+
+    if (style->variablesHash == NULL)
+	return(NULL);
+    if (name == NULL)
+	return(NULL);
+
+    return((xmlXPathObjectPtr)
+	   xmlHashLookup2((xmlHashTablePtr) style->variablesHash,
+	                  name, ns_uri));
+}
+
+
+/**
+ * xsltFreeVariableHashes:
+ * @style: an XSLT stylesheet
+ *
+ * Free up the memory used by xsltAddVariable/xsltGetVariable mechanism
+ */
+void
+xsltFreeVariableHashes(xsltStylesheetPtr style) {
+    if (style->variablesHash != NULL)
+	xmlHashFree((xmlHashTablePtr) style->variablesHash,
+		    (xmlHashDeallocator) xmlXPathFreeObject);
+}
+
diff --git a/libxslt/variables.h b/libxslt/variables.h
new file mode 100644
index 0000000000000000000000000000000000000000..633bc556eed679d8b110123258f2cedb2a0c1246_bGlieHNsdC92YXJpYWJsZXMuaA==
--- /dev/null
+++ b/libxslt/variables.h
@@ -0,0 +1,32 @@
+/*
+ * variable.h: interface for the variable matching and lookup.
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel.Veillard@imag.fr
+ */
+
+#ifndef __XML_XSLT_VARIABLES_H__
+#define __XML_XSLT_VARIABLES_H__
+
+#include <libxml/xpath.h>
+#include "xsltInternals.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void			xsltFreeVariableHashes	(xsltStylesheetPtr style);
+xmlXPathObjectPtr	xsltVariableLookup	(xsltStylesheetPtr style,
+						 const xmlChar *name,
+						 const xmlChar *ns_uri);
+int			xsltRegisterVariable	(xsltStylesheetPtr style,
+						 const xmlChar *name,
+						 const xmlChar *ns_uri,
+						 xmlXPathObjectPtr value);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_XSLT_VARIABLES_H__ */
+
diff --git a/libxslt/xslt.c b/libxslt/xslt.c
index 2ba2d52a199b759efe1a1a9ae86f9ab52f389e48_bGlieHNsdC94c2x0LmM=..633bc556eed679d8b110123258f2cedb2a0c1246_bGlieHNsdC94c2x0LmM= 100644
--- a/libxslt/xslt.c
+++ b/libxslt/xslt.c
@@ -23,6 +23,7 @@
 #include "xslt.h"
 #include "xsltInternals.h"
 #include "pattern.h"
+#include "variables.h"
 #include "xsltutils.h"
 
 #define DEBUG_PARSING
@@ -161,6 +162,7 @@
 	return;
 
     xsltFreeTemplateHashes(sheet);
+    xsltFreeVariableHashes(sheet);
     xsltFreeTemplateList(sheet->templates);
     if (sheet->doc != NULL)
 	xmlFreeDoc(sheet->doc);
@@ -704,9 +706,10 @@
 void
 xsltParseStylesheetTop(xsltStylesheetPtr style, xmlNodePtr top) {
     xmlNodePtr cur;
+    xmlChar *prop;
 #ifdef DEBUG_PARSING
     int templates = 0;
 #endif
 
     if (top == NULL)
 	return;
@@ -707,9 +710,23 @@
 #ifdef DEBUG_PARSING
     int templates = 0;
 #endif
 
     if (top == NULL)
 	return;
+
+    prop = xmlGetNsProp(cur, (const xmlChar *)"version", XSLT_NAMESPACE);
+    if (prop == NULL) {
+	xsltGenericError(xsltGenericErrorContext,
+	    "xsl:version is missing: document may not be a stylesheet\n");
+    } else {
+	if (!xmlStrEqual(prop, (const xmlChar *)"1.0")) {
+	    xsltGenericError(xsltGenericErrorContext,
+		"xsl:version: only 1.0 features are supported\n");
+	    TODO /* set up compatibility when not XSLT 1.0 */
+	}
+	xmlFree(prop);
+    }
+
     cur = top->children;
 
     while (cur != NULL) {
diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h
index 2ba2d52a199b759efe1a1a9ae86f9ab52f389e48_bGlieHNsdC94c2x0SW50ZXJuYWxzLmg=..633bc556eed679d8b110123258f2cedb2a0c1246_bGlieHNsdC94c2x0SW50ZXJuYWxzLmg= 100644
--- a/libxslt/xsltInternals.h
+++ b/libxslt/xsltInternals.h
@@ -45,6 +45,15 @@
 typedef struct _xsltStylesheet xsltStylesheet;
 typedef xsltStylesheet *xsltStylesheetPtr;
 struct _xsltStylesheet {
+    /*
+     * The stylesheet import relation is kept as a tree
+     */
+    struct _xsltStylesheet *parent;
+    struct _xsltStylesheet *imports;
+
+    /*
+     * General data on the style sheet document
+     */
     xmlDocPtr doc;		/* the parsed XML stylesheet */
     xmlHashTablePtr stripSpaces;/* the hash table of the strip-space
 				   preserve space and cdata-section elements */
@@ -55,6 +64,11 @@
     xsltTemplatePtr templates;	/* the ordered list of templates */
     void *templatesHash;	/* hash table or wherever compiled templates
 				   informations are stored */
+    /*
+     * Variable descriptions
+     */
+    void *variablesHash;	/* hash table or wherever variables
+				   informations are stored */
 
     /*
      * Output related stuff.
@@ -63,7 +77,7 @@
     xmlChar *methodURI;		/* associated namespace if any */
     xmlChar *version;		/* version string */
     xmlChar *encoding;		/* encoding string */
-    int omitXmlDeclaration;   /* omit-xml-declaration = "yes" | "no" */
+    int omitXmlDeclaration;     /* omit-xml-declaration = "yes" | "no" */
     int standalone;             /* standalone = "yes" | "no" */
     xmlChar *doctypePublic;     /* doctype-public string */
     xmlChar *doctypeSystem;     /* doctype-system string */
diff --git a/libxslt/xsltutils.h b/libxslt/xsltutils.h
index 2ba2d52a199b759efe1a1a9ae86f9ab52f389e48_bGlieHNsdC94c2x0dXRpbHMuaA==..633bc556eed679d8b110123258f2cedb2a0c1246_bGlieHNsdC94c2x0dXRpbHMuaA== 100644
--- a/libxslt/xsltutils.h
+++ b/libxslt/xsltutils.h
@@ -22,6 +22,8 @@
  */
 xmlChar *xmlSplitQName2(const xmlChar *name, xmlChar **prefix);
 void xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs);
+xmlAttrPtr xmlSetNsProp	(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
+			 const xmlChar *value);
 
 /*
  * Useful macros