applied patch from Robert Stepanek to start import os schemas support,

* xmlschemas.c: applied patch from Robert Stepanek to start
  import os schemas support, cleaned up stuff and the patch.
* test/schemas/import0_0.* result/schemas/import0_0_0*: added test
  to regression, fixed a few regressions too.
Daniel
diff --git a/xmlschemas.c b/xmlschemas.c
index f64c1b5..6976cc7 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -133,6 +133,15 @@
     xmlSchemaAttrStatePtr attr;
 };
 
+/*
+ * These are the entries in the schemas importSchemas hash table
+ */
+typedef struct _xmlSchemaImport xmlSchemaImport;
+typedef xmlSchemaImport *xmlSchemaImportPtr;
+struct _xmlSchemaImport {
+    const xmlChar *schemaLocation;
+    xmlSchemaPtr schema;
+};
 
 /************************************************************************
  * 									*
@@ -398,6 +407,23 @@
 }
 
 /**
+ * xmlSchemaFreeImport:
+ * @import:  a schema import structure
+ *
+ * Deallocate an import structure
+ */
+static void
+xmlSchemaFreeImport(xmlSchemaImportPtr import)
+{
+    if (import == NULL)
+        return;
+
+    xmlSchemaFree(import->schema);
+    xmlFree((xmlChar *) import->schemaLocation);
+    xmlFree(import);
+}
+
+/**
  * xmlSchemaFreeNotation:
  * @schema:  a schema notation structure
  *
@@ -522,6 +548,8 @@
         return;
     if (type->name != NULL)
         xmlFree((xmlChar *) type->name);
+    if (type->ref != NULL)
+        xmlFree((xmlChar *) type->ref);
     if (type->base != NULL)
         xmlFree((xmlChar *) type->base);
     if (type->baseNs != NULL)
@@ -577,6 +605,9 @@
     if (schema->groupDecl != NULL)
         xmlHashFree(schema->groupDecl,
                     (xmlHashDeallocator) xmlSchemaFreeType);
+    if (schema->schemasImports != NULL)
+	xmlHashFree(schema->schemasImports,
+		    (xmlHashDeallocator) xmlSchemaFreeImport);
     if (schema->annot != NULL)
         xmlSchemaFreeAnnot(schema->annot);
     if (schema->doc != NULL)
@@ -845,6 +876,7 @@
                  const xmlChar * namespace)
 {
     xmlSchemaTypePtr ret;
+    xmlSchemaImportPtr import;
 
     if (name == NULL)
         return (NULL);
@@ -854,6 +886,11 @@
             return (ret);
     }
     ret = xmlSchemaGetPredefinedType(name, namespace);
+    if (ret != NULL)
+	return (ret);
+    import = xmlHashLookup(schema->schemasImports, namespace);
+    if (import != NULL)
+	ret = xmlSchemaGetType(import->schema, name, namespace);
 #ifdef DEBUG
     if (ret == NULL) {
         if (namespace == NULL)
@@ -2216,8 +2253,10 @@
         name = xmlStrdup((xmlChar *) buf);
     }
     type = xmlSchemaAddGroup(ctxt, schema, name);
+    xmlFree(name);
     if (type == NULL)
         return (NULL);
+
     type->node = node;
     type->type = XML_SCHEMA_TYPE_GROUP;
     type->id = xmlGetProp(node, BAD_CAST "id");
@@ -2319,6 +2358,63 @@
 }
 
 /**
+ * xmlSchemaImportSchema
+ * 
+ * @ctxt:  a schema validation context
+ * @schemaLocation:  an URI defining where to find the imported schema
+ *
+ * import a XML schema
+ * *WARNING* this interface is highly subject to change
+ *
+ * Returns -1 in case of error and 1 in case of success.
+ */
+static xmlSchemaImportPtr
+xmlSchemaImportSchema(xmlSchemaParserCtxtPtr ctxt,
+                      const xmlChar *schemaLocation)
+{
+    xmlSchemaImportPtr import;
+    xmlSchemaParserCtxtPtr newctxt;
+
+    newctxt = xmlSchemaNewParserCtxt((const char *) schemaLocation);
+    if (newctxt == NULL) {
+        xmlSchemaPErrMemory(NULL, "allocating parser context",
+                            NULL);
+        return (NULL);
+    }
+    xmlSchemaSetParserErrors(newctxt, ctxt->error, ctxt->warning,
+	                     ctxt->userData);
+
+    import = (xmlSchemaImport*) xmlMalloc(sizeof(xmlSchemaImport));
+    if (import == NULL) {
+        xmlSchemaPErrMemory(NULL, "allocating imported schema",
+                            NULL);
+	xmlSchemaFreeParserCtxt(newctxt);
+        return (NULL);
+    }
+
+    memset(import, 0, sizeof(xmlSchemaImport));
+    import->schemaLocation = xmlStrdup(schemaLocation);
+    import->schema = xmlSchemaParse(newctxt);
+
+    if (import->schema == NULL) {
+        /* FIXME use another error enum here ? */
+        xmlSchemaPErr(ctxt, NULL, XML_SCHEMAS_ERR_INTERNAL,
+	              "failed to import schema at location %s\n",
+		      schemaLocation, NULL);
+
+	xmlSchemaFreeParserCtxt(newctxt);
+	if (import->schemaLocation != NULL)
+	    xmlFree((xmlChar *)import->schemaLocation);
+	xmlFree(import);
+	return NULL;
+    }
+
+    xmlSchemaFreeParserCtxt(newctxt);
+    return import;
+}
+
+
+/**
  * xmlSchemaParseImport:
  * @ctxt:  a schema validation context
  * @schema:  the schema being built
@@ -2335,11 +2431,13 @@
                      xmlNodePtr node)
 {
     xmlNodePtr child = NULL;
+    xmlSchemaImportPtr import = NULL;
     xmlChar *namespace;
     xmlChar *schemaLocation;
-    xmlChar *previous;
+    const xmlChar *previous;
     xmlURIPtr check;
 
+
     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
         return (-1);
 
@@ -2359,6 +2457,8 @@
     }
     schemaLocation = xmlGetProp(node, BAD_CAST "schemaLocation");
     if (schemaLocation != NULL) {
+        xmlChar *base = NULL;
+        xmlChar *URI = NULL;
         check = xmlParseURI((const char *) schemaLocation);
         if (check == NULL) {
             xmlSchemaPErr2(ctxt, node, child,
@@ -2372,6 +2472,17 @@
         } else {
             xmlFreeURI(check);
         }
+	base = xmlNodeGetBase(node->doc, node);
+	if (base == NULL) {
+	    URI = xmlBuildURI(schemaLocation, node->doc->URL);
+	} else {
+	    URI = xmlBuildURI(schemaLocation, base);
+	}
+	if (base != NULL) xmlFree(base);
+	if (URI != NULL) {
+	    xmlFree(schemaLocation);
+	    schemaLocation = URI;
+	}
     }
     if (schema->schemasImports == NULL) {
         schema->schemasImports = xmlHashCreate(10);
@@ -2388,8 +2499,13 @@
         }
     }
     if (namespace == NULL) {
-        previous = xmlHashLookup(schema->schemasImports,
-                                 XML_SCHEMAS_DEFAULT_NAMESPACE);
+        import = xmlHashLookup(schema->schemasImports,
+	                               XML_SCHEMAS_DEFAULT_NAMESPACE);
+	if (import != NULL)
+            previous = import->schemaLocation;
+	else
+	    previous = NULL;
+
         if (schemaLocation != NULL) {
             if (previous != NULL) {
                 if (!xmlStrEqual(schemaLocation, previous)) {
@@ -2399,13 +2515,27 @@
                                    schemaLocation, NULL);
                 }
             } else {
+	        import = xmlSchemaImportSchema(ctxt, schemaLocation);
+		if (import == NULL) {
+		    if (schemaLocation != NULL)
+			xmlFree(schemaLocation);
+		    if (namespace != NULL)
+			xmlFree(namespace);
+		    return (-1);
+		}
                 xmlHashAddEntry(schema->schemasImports,
                                 XML_SCHEMAS_DEFAULT_NAMESPACE,
-                                schemaLocation);
+                                import);
             }
+	    xmlFree(schemaLocation);
         }
     } else {
-        previous = xmlHashLookup(schema->schemasImports, namespace);
+        import = xmlHashLookup(schema->schemasImports, namespace);
+	if (import != NULL)
+	    previous = import->schemaLocation;
+	else
+	    previous = NULL;
+
         if (schemaLocation != NULL) {
             if (previous != NULL) {
                 if (!xmlStrEqual(schemaLocation, previous)) {
@@ -2415,11 +2545,22 @@
                                    namespace, schemaLocation);
                 }
             } else {
+	        import = xmlSchemaImportSchema(ctxt, schemaLocation);
+		if (import == NULL) {
+		    if (schemaLocation != NULL)
+			xmlFree(schemaLocation);
+		    if (namespace != NULL)
+			xmlFree(namespace);
+		    return (-1);
+		}
                 xmlHashAddEntry(schema->schemasImports,
-                                namespace, schemaLocation);
+                                namespace, import);
             }
         }
+	xmlFree(namespace);
     }
+    if (schemaLocation != NULL)
+	xmlFree(schemaLocation);
 
     child = node->children;
     while (IS_SCHEMA(child, "annotation")) {
@@ -4271,6 +4412,7 @@
 	xmlSchemaPErr(ctxt, (xmlNodePtr) doc,
 		      XML_SCHEMAP_NOROOT,
 		      "schemas has no root", NULL, NULL);
+	xmlFreeDoc(doc);
         return (NULL);
     }
 
@@ -4338,8 +4480,10 @@
      * Then do the parsing for good
      */
     ret = xmlSchemaParseSchema(ctxt, root);
-    if (ret == NULL)
+    if (ret == NULL) {
+	xmlFreeDoc(doc);
         return (NULL);
+    }
     ret->doc = doc;
 
     /*