lot of bug fixes, cleanup, starting to add proper namespace support too.

* xmlschemas.c xmlschemastypes.c include/libxml/xmlerror.h
  include/libxml/schemasInternals.h: lot of bug fixes, cleanup,
  starting to add proper namespace support too.
* test/schemas/* result/schemas/*: added a number of tests
  fixed the result from some regression tests too.
Daniel
diff --git a/xmlschemas.c b/xmlschemas.c
index 6976cc7..58a460e 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -24,6 +24,7 @@
 #include <libxml/xmlschemastypes.h>
 #include <libxml/xmlautomata.h>
 #include <libxml/xmlregexp.h>
+#include <libxml/dict.h>
 
 /* #define DEBUG 1 */
 
@@ -67,11 +68,14 @@
     int nberrors;
     xmlStructuredErrorFunc serror;
 
+    xmlSchemaPtr topschema;	/* The main schema */
+    xmlHashTablePtr namespaces;	/* Hash table of namespaces to schemas */
+
     xmlSchemaPtr schema;        /* The schema in use */
-    xmlChar *container;         /* the current element, group, ... */
+    const xmlChar *container;   /* the current element, group, ... */
     int counter;
 
-    xmlChar *URL;
+    const xmlChar *URL;
     xmlDocPtr doc;
 
     const char *buffer;
@@ -84,6 +88,8 @@
     xmlAutomataStatePtr start;
     xmlAutomataStatePtr end;
     xmlAutomataStatePtr state;
+
+    xmlDictPtr dict;		/* dictionnary for interned string names */
 };
 
 
@@ -150,7 +156,7 @@
  ************************************************************************/
 static int xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
                                         xmlSchemaTypePtr type,
-                                        xmlChar * value);
+                                        const xmlChar * value);
 
 /************************************************************************
  *									*
@@ -343,6 +349,8 @@
         return (NULL);
     }
     memset(ret, 0, sizeof(xmlSchema));
+    xmlDictReference(ctxt->dict);
+    ret->dict = ctxt->dict;
 
     return (ret);
 }
@@ -419,7 +427,6 @@
         return;
 
     xmlSchemaFree(import->schema);
-    xmlFree((xmlChar *) import->schemaLocation);
     xmlFree(import);
 }
 
@@ -434,8 +441,6 @@
 {
     if (nota == NULL)
         return;
-    if (nota->name != NULL)
-        xmlFree((xmlChar *) nota->name);
     xmlFree(nota);
 }
 
@@ -450,16 +455,6 @@
 {
     if (attr == NULL)
         return;
-    if (attr->name != NULL)
-        xmlFree((xmlChar *) attr->name);
-    if (attr->ref != NULL)
-        xmlFree((xmlChar *) attr->ref);
-    if (attr->refNs != NULL)
-        xmlFree((xmlChar *) attr->refNs);
-    if (attr->typeName != NULL)
-        xmlFree((xmlChar *) attr->typeName);
-    if (attr->typeNs != NULL)
-        xmlFree((xmlChar *) attr->typeNs);
     xmlFree(attr);
 }
 
@@ -474,12 +469,6 @@
 {
     if (attr == NULL)
         return;
-    if (attr->name != NULL)
-        xmlFree((xmlChar *) attr->name);
-    if (attr->ref != NULL)
-        xmlFree((xmlChar *) attr->ref);
-    if (attr->refNs != NULL)
-        xmlFree((xmlChar *) attr->refNs);
     xmlFree(attr);
 }
 
@@ -494,16 +483,6 @@
 {
     if (elem == NULL)
         return;
-    if (elem->name != NULL)
-        xmlFree((xmlChar *) elem->name);
-    if (elem->namedType != NULL)
-        xmlFree((xmlChar *) elem->namedType);
-    if (elem->namedTypeNs != NULL)
-        xmlFree((xmlChar *) elem->namedTypeNs);
-    if (elem->ref != NULL)
-        xmlFree((xmlChar *) elem->ref);
-    if (elem->refNs != NULL)
-        xmlFree((xmlChar *) elem->refNs);
     if (elem->annot != NULL)
         xmlSchemaFreeAnnot(elem->annot);
     if (elem->contModel != NULL)
@@ -522,10 +501,6 @@
 {
     if (facet == NULL)
         return;
-    if (facet->value != NULL)
-        xmlFree((xmlChar *) facet->value);
-    if (facet->id != NULL)
-        xmlFree((xmlChar *) facet->id);
     if (facet->val != NULL)
         xmlSchemaFreeValue(facet->val);
     if (facet->regexp != NULL)
@@ -546,14 +521,6 @@
 {
     if (type == NULL)
         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)
-        xmlFree((xmlChar *) type->baseNs);
     if (type->annot != NULL)
         xmlSchemaFreeAnnot(type->annot);
     if (type->facets != NULL) {
@@ -581,12 +548,6 @@
     if (schema == NULL)
         return;
 
-    if (schema->id != NULL)
-        xmlFree((xmlChar *) schema->id);
-    if (schema->targetNamespace != NULL)
-        xmlFree((xmlChar *) schema->targetNamespace);
-    if (schema->name != NULL)
-        xmlFree((xmlChar *) schema->name);
     if (schema->notaDecl != NULL)
         xmlHashFree(schema->notaDecl,
                     (xmlHashDeallocator) xmlSchemaFreeNotation);
@@ -612,6 +573,7 @@
         xmlSchemaFreeAnnot(schema->annot);
     if (schema->doc != NULL)
         xmlFreeDoc(schema->doc);
+    xmlDictFree(schema->dict);
 
     xmlFree(schema);
 }
@@ -856,12 +818,168 @@
 #endif /* LIBXML_OUTPUT_ENABLED */
 
 /************************************************************************
+ *									*
+ * 			Utilities					*
+ *									*
+ ************************************************************************/
+/**
+ * numberedString:
+ * @prefix:  the string prefix
+ * @number:  the number
+ *
+ * Build a new numbered string
+ *
+ * Returns the new string
+ */
+
+/**
+ * xmlSchemaGetProp:
+ * @ctxt: the parser context
+ * @node: the node
+ * @name: the property name
+ * 
+ * Read a attribute value and internalize the string
+ *
+ * Returns the string or NULL if not present.
+ */
+static const xmlChar *
+xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
+                 const char *name)
+{
+    xmlChar *val;
+    const xmlChar *ret;
+
+    val = xmlGetProp(node, BAD_CAST name);
+    if (val == NULL)
+        return(NULL);
+    ret = xmlDictLookup(ctxt->dict, val, -1);
+    xmlFree(val);
+    return(ret);
+}
+
+/**
+ * xmlSchemaGetNamespace:
+ * @ctxt: the parser context
+ * @schema: the schemas containing the declaration
+ * @node: the node
+ * @qname: the QName to analyze
+ * 
+ * Find the namespace name for the given declaration.
+ *
+ * Returns the local name for that declaration, as well as the namespace name
+ */
+static const xmlChar *
+xmlSchemaGetNamespace(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+	              xmlNodePtr node, const xmlChar *qname,
+	     const xmlChar **namespace) {
+    int len;
+    const xmlChar *name, *prefix, *def = NULL;
+    xmlNsPtr ns;
+
+    *namespace = NULL;
+    
+    if (xmlStrEqual(node->name, BAD_CAST "element") ||
+        xmlStrEqual(node->name, BAD_CAST "attribute") ||
+	xmlStrEqual(node->name, BAD_CAST "simpleType") ||
+	xmlStrEqual(node->name, BAD_CAST "complexType")) {
+	def = xmlSchemaGetProp(ctxt, node, "targetNamespace");
+    }
+
+    qname = xmlDictLookup(ctxt->dict, qname, -1); /* intern the string */
+    name = xmlSplitQName3(qname, &len);
+    if (name == NULL) {
+        if (def == NULL) {
+	    if (xmlStrEqual(node->name, BAD_CAST "element")) {
+		if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
+		    *namespace = schema->targetNamespace;
+	    } else if (xmlStrEqual(node->name, BAD_CAST "attribute")) {
+		if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
+		    *namespace = schema->targetNamespace;
+	    } else if ((xmlStrEqual(node->name, BAD_CAST "simpleType")) ||
+	               (xmlStrEqual(node->name, BAD_CAST "complexType"))) {
+		*namespace = schema->targetNamespace;
+	    }
+	} else {
+	    *namespace = def;
+	}
+	return(qname);
+    }
+    name = xmlDictLookup(ctxt->dict, name, -1);
+    prefix = xmlDictLookup(ctxt->dict, qname, len);
+    if (def != NULL) {
+        xmlSchemaPErr(ctxt, node, XML_SCHEMAP_DEF_AND_PREFIX,
+                      "%s: presence of both prefix %s and targetNamespace\n",
+                      node->name, prefix);
+    }
+    ns = xmlSearchNs(node->doc, node, prefix);
+    if (ns == NULL) {
+        xmlSchemaPErr(ctxt, node, XML_SCHEMAP_PREFIX_UNDEFINED,
+                      "%s: the QName prefix %s is undefined\n",
+                      node->name, prefix);
+	return(name);
+    }
+    *namespace = xmlDictLookup(ctxt->dict, ns->href, -1);
+    return(name);
+}
+
+/************************************************************************
  * 									*
  * 			Parsing functions				*
  * 									*
  ************************************************************************/
 
 /**
+ * xmlSchemaGetElem:
+ * @schema:  the schemas context
+ * @name:  the element name
+ * @ns:  the element namespace
+ *
+ * Lookup a an element in the schemas or the accessible schemas
+ *
+ * Returns the element definition or NULL if not found.
+ */
+static xmlSchemaElementPtr
+xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
+                 const xmlChar * namespace)
+{
+    xmlSchemaElementPtr ret;
+    xmlSchemaImportPtr import;
+
+    if ((name == NULL) || (schema == NULL))
+        return (NULL);
+    
+    if (namespace == NULL) {
+        ret = xmlHashLookup2(schema->elemDecl, name, namespace);
+        if (ret != NULL)
+            return (ret);
+    } else if ((schema->flags & XML_SCHEMAS_QUALIF_ELEM) == 0) {
+        if (xmlStrEqual(namespace, schema->targetNamespace))
+	    ret = xmlHashLookup2(schema->elemDecl, name, NULL);
+	else
+	    ret = xmlHashLookup2(schema->elemDecl, name, namespace);
+        if (ret != NULL)
+            return (ret);
+    } else {
+	ret = xmlHashLookup2(schema->elemDecl, name, namespace);
+        if (ret != NULL)
+            return (ret);
+    }
+    import = xmlHashLookup(schema->schemasImports, namespace);
+    if (import != NULL)
+	ret = xmlSchemaGetElem(import->schema, name, namespace);
+#ifdef DEBUG
+    if (ret == NULL) {
+        if (namespace == NULL)
+            fprintf(stderr, "Unable to lookup type %s", name);
+        else
+            fprintf(stderr, "Unable to lookup type %s:%s", name,
+                    namespace);
+    }
+#endif
+    return (ret);
+}
+
+/**
  * xmlSchemaGetType:
  * @schema:  the schemas context
  * @name:  the type name
@@ -965,7 +1083,7 @@
         return (NULL);
     }
     memset(ret, 0, sizeof(xmlSchemaNotation));
-    ret->name = xmlStrdup(name);
+    ret->name = xmlDictLookup(ctxt->dict, name, -1);
     val = xmlHashAddEntry2(schema->notaDecl, name, schema->targetNamespace,
                            ret);
     if (val != 0) {
@@ -973,7 +1091,6 @@
 		      XML_SCHEMAP_REDEFINED_NOTATION,
                       "Notation %s already defined\n",
                       name, NULL);
-        xmlFree((char *) ret->name);
         xmlFree(ret);
         return (NULL);
     }
@@ -986,7 +1103,7 @@
  * @ctxt:  a schema validation context
  * @schema:  the schema being built
  * @name:  the item name
- * @container:  the container's name
+ * @namespace:  the namespace
  *
  * Add an XML schema Attrribute declaration
  * *WARNING* this interface is highly subject to change
@@ -995,7 +1112,7 @@
  */
 static xmlSchemaAttributePtr
 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
-                      const xmlChar * name)
+                      const xmlChar * name, const xmlChar * namespace)
 {
     xmlSchemaAttributePtr ret = NULL;
     int val;
@@ -1003,6 +1120,12 @@
     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
         return (NULL);
 
+#ifdef DEBUG
+    fprintf(stderr, "Adding attribute %s\n", name);
+    if (namespace != NULL)
+	fprintf(stderr, "  target namespace %s\n", namespace);
+#endif
+
     if (schema->attrDecl == NULL)
         schema->attrDecl = xmlHashCreate(10);
     if (schema->attrDecl == NULL)
@@ -1014,7 +1137,8 @@
         return (NULL);
     }
     memset(ret, 0, sizeof(xmlSchemaAttribute));
-    ret->name = xmlStrdup(name);
+    ret->name = xmlDictLookup(ctxt->dict, name, -1);
+    ret->targetNamespace = xmlDictLookup(ctxt->dict, namespace, -1);
     val = xmlHashAddEntry3(schema->attrDecl, name,
                            schema->targetNamespace, ctxt->container, ret);
     if (val != 0) {
@@ -1022,7 +1146,6 @@
 		      XML_SCHEMAP_REDEFINED_ATTR,
                       "Attribute %s already defined\n",
                       name, NULL);
-        xmlFree((char *) ret->name);
         xmlFree(ret);
         return (NULL);
     }
@@ -1062,7 +1185,7 @@
         return (NULL);
     }
     memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
-    ret->name = xmlStrdup(name);
+    ret->name = xmlDictLookup(ctxt->dict, name, -1);
     val = xmlHashAddEntry3(schema->attrgrpDecl, name,
                            schema->targetNamespace, ctxt->container, ret);
     if (val != 0) {
@@ -1070,7 +1193,6 @@
 		      XML_SCHEMAP_REDEFINED_ATTRGROUP,
                       "Attribute group %s already defined\n",
                       name, NULL);
-        xmlFree((char *) ret->name);
         xmlFree(ret);
         return (NULL);
     }
@@ -1099,6 +1221,12 @@
     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
         return (NULL);
 
+#ifdef DEBUG
+    fprintf(stderr, "Adding element %s\n", name);
+    if (namespace != NULL)
+	fprintf(stderr, "  target namespace %s\n", namespace);
+#endif
+
     if (schema->elemDecl == NULL)
         schema->elemDecl = xmlHashCreate(10);
     if (schema->elemDecl == NULL)
@@ -1110,13 +1238,14 @@
         return (NULL);
     }
     memset(ret, 0, sizeof(xmlSchemaElement));
-    ret->name = xmlStrdup(name);
+    ret->name = xmlDictLookup(ctxt->dict, name, -1);
+    ret->targetNamespace = xmlDictLookup(ctxt->dict, namespace, -1);
     val = xmlHashAddEntry3(schema->elemDecl, name,
                            namespace, ctxt->container, ret);
     if (val != 0) {
         char buf[100];
 
-        snprintf(buf, 99, "privatieelem%d", ctxt->counter++ + 1);
+        snprintf(buf, 99, "privatieelem %d", ctxt->counter++ + 1);
         val = xmlHashAddEntry3(schema->elemDecl, name, (xmlChar *) buf,
                                namespace, ret);
         if (val != 0) {
@@ -1124,7 +1253,6 @@
 			  XML_SCHEMAP_REDEFINED_ELEMENT,
 			  "Element %s already defined\n",
 			  name, NULL);
-            xmlFree((char *) ret->name);
             xmlFree(ret);
             return (NULL);
         }
@@ -1137,6 +1265,7 @@
  * @ctxt:  a schema validation context
  * @schema:  the schema being built
  * @name:  the item name
+ * @namespace:  the namespace
  *
  * Add an XML schema Simple Type definition
  * *WARNING* this interface is highly subject to change
@@ -1145,7 +1274,7 @@
  */
 static xmlSchemaTypePtr
 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
-                 const xmlChar * name)
+                 const xmlChar * name, const xmlChar * namespace)
 {
     xmlSchemaTypePtr ret = NULL;
     int val;
@@ -1153,6 +1282,12 @@
     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
         return (NULL);
 
+#ifdef DEBUG
+    fprintf(stderr, "Adding type %s\n", name);
+    if (namespace != NULL)
+	fprintf(stderr, "  target namespace %s\n", namespace);
+#endif
+
     if (schema->typeDecl == NULL)
         schema->typeDecl = xmlHashCreate(10);
     if (schema->typeDecl == NULL)
@@ -1164,15 +1299,13 @@
         return (NULL);
     }
     memset(ret, 0, sizeof(xmlSchemaType));
-    ret->name = xmlStrdup(name);
-    val = xmlHashAddEntry2(schema->typeDecl, name, schema->targetNamespace,
-                           ret);
+    ret->name = xmlDictLookup(ctxt->dict, name, -1);
+    val = xmlHashAddEntry2(schema->typeDecl, name, namespace, ret);
     if (val != 0) {
 	xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
 		      XML_SCHEMAP_REDEFINED_TYPE,
                       "Type %s already defined\n",
                       name, NULL);
-        xmlFree((char *) ret->name);
         xmlFree(ret);
         return (NULL);
     }
@@ -1213,7 +1346,7 @@
         return (NULL);
     }
     memset(ret, 0, sizeof(xmlSchemaType));
-    ret->name = xmlStrdup(name);
+    ret->name = xmlDictLookup(ctxt->dict, name, -1);
     val =
         xmlHashAddEntry2(schema->groupDecl, name, schema->targetNamespace,
                          ret);
@@ -1222,7 +1355,6 @@
 		      XML_SCHEMAP_REDEFINED_GROUP,
                       "Group %s already defined\n",
                       name, NULL);
-        xmlFree((char *) ret->name);
         xmlFree(ret);
         return (NULL);
     }
@@ -1250,24 +1382,26 @@
  * Returns the NCName or NULL if not found, and also update @namespace
  *    with the namespace URI
  */
-static xmlChar *
+static const xmlChar *
 xmlGetQNameProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
-                const char *name, xmlChar ** namespace)
+                const char *name, const xmlChar ** namespace)
 {
-    xmlChar *val, *ret, *prefix;
+    const xmlChar *val;
     xmlNsPtr ns;
+    const xmlChar *ret, *prefix;
+    int len;
 
-
-    if (namespace != NULL)
-        *namespace = NULL;
-    val = xmlGetProp(node, (const xmlChar *) name);
+    *namespace = NULL;
+    val = xmlSchemaGetProp(ctxt, node, name);
     if (val == NULL)
         return (NULL);
 
-    ret = xmlSplitQName2(val, &prefix);
-    if (ret == NULL)
+    ret = xmlSplitQName3(val, &len);
+    if (ret == NULL) {
         return (val);
-    xmlFree(val);
+    }
+    ret = xmlDictLookup(ctxt->dict, ret, -1);
+    prefix = xmlDictLookup(ctxt->dict, val, len);
 
     ns = xmlSearchNs(node->doc, node, prefix);
     if (ns == NULL) {
@@ -1275,9 +1409,8 @@
                       "Attribute %s: the QName prefix %s is undefined\n",
                       (const xmlChar *) name, prefix);
     } else {
-        *namespace = xmlStrdup(ns->href);
+        *namespace = xmlDictLookup(ctxt->dict, ns->href, -1);
     }
-    xmlFree(prefix);
     return (ret);
 }
 
@@ -1293,16 +1426,15 @@
 static int
 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
 {
-    xmlChar *val, *cur;
+    const xmlChar *val, *cur;
     int ret = 0;
 
-    val = xmlGetProp(node, (const xmlChar *) "maxOccurs");
+    val = xmlSchemaGetProp(ctxt, node, "maxOccurs");
     if (val == NULL)
         return (1);
 
     if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
-        xmlFree(val);
-        return (UNBOUNDED);     /* encoding it with -1 might be another option */
+        return (UNBOUNDED);  /* encoding it with -1 might be another option */
     }
 
     cur = val;
@@ -1317,10 +1449,8 @@
     if (*cur != 0) {
         xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_MAXOCCURS,
                       "invalid value for maxOccurs: %s\n", val, NULL);
-        xmlFree(val);
         return (1);
     }
-    xmlFree(val);
     return (ret);
 }
 
@@ -1336,10 +1466,10 @@
 static int
 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
 {
-    xmlChar *val, *cur;
+    const xmlChar *val, *cur;
     int ret = 0;
 
-    val = xmlGetProp(node, (const xmlChar *) "minOccurs");
+    val = xmlSchemaGetProp(ctxt, node, "minOccurs");
     if (val == NULL)
         return (1);
 
@@ -1355,10 +1485,8 @@
     if (*cur != 0) {
         xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_MINOCCURS,
                       "invalid value for minOccurs: %s\n", val, NULL);
-        xmlFree(val);
         return (1);
     }
-    xmlFree(val);
     return (ret);
 }
 
@@ -1378,9 +1506,9 @@
 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
                   const char *name, int def)
 {
-    xmlChar *val;
+    const xmlChar *val;
 
-    val = xmlGetProp(node, (const xmlChar *) name);
+    val = xmlSchemaGetProp(ctxt, node, name);
     if (val == NULL)
         return (def);
 
@@ -1393,7 +1521,6 @@
                       "Attribute %s: the value %s is not boolean\n",
                       (const xmlChar *) name, val);
     }
-    xmlFree(val);
     return (def);
 }
 
@@ -1533,7 +1660,7 @@
 {
     xmlSchemaFacetPtr facet;
     xmlNodePtr child = NULL;
-    xmlChar *value;
+    const xmlChar *value;
 
     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
         return (NULL);
@@ -1544,7 +1671,7 @@
         return (NULL);
     }
     facet->node = node;
-    value = xmlGetProp(node, (const xmlChar *) "value");
+    value = xmlSchemaGetProp(ctxt, node, "value");
     if (value == NULL) {
         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
                        "Facet %s has no value\n", node->name, NULL);
@@ -1581,7 +1708,7 @@
         xmlSchemaFreeFacet(facet);
         return (NULL);
     }
-    facet->id = xmlGetProp(node, (const xmlChar *) "id");
+    facet->id = xmlSchemaGetProp(ctxt, node, "id");
     facet->value = value;
     child = node->children;
 
@@ -1619,7 +1746,7 @@
     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
         return (NULL);
     snprintf((char *) name, 30, "any %d", ctxt->counter++ + 1);
-    type = xmlSchemaAddType(ctxt, schema, name);
+    type = xmlSchemaAddType(ctxt, schema, name, NULL);
     if (type == NULL)
         return (NULL);
     type->node = node;
@@ -1656,13 +1783,13 @@
 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                        xmlNodePtr node)
 {
-    xmlChar *name;
+    const xmlChar *name;
     xmlSchemaNotationPtr ret;
     xmlNodePtr child = NULL;
 
     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
         return (NULL);
-    name = xmlGetProp(node, (const xmlChar *) "name");
+    name = xmlSchemaGetProp(ctxt, node, "name");
     if (name == NULL) {
         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
                        "Notation has no name\n", NULL, NULL);
@@ -1670,7 +1797,6 @@
     }
     ret = xmlSchemaAddNotation(ctxt, schema, name);
     if (ret == NULL) {
-        xmlFree(name);
         return (NULL);
     }
     child = node->children;
@@ -1702,22 +1828,24 @@
 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
                            xmlSchemaPtr schema, xmlNodePtr node)
 {
-    xmlChar *processContents;
+    const xmlChar *processContents;
     xmlSchemaAttributePtr ret;
     xmlNodePtr child = NULL;
     char name[100];
+    const xmlChar *local, *ns;
+
 
     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
         return (NULL);
 
     snprintf(name, 99, "anyattr %d", ctxt->counter++ + 1);
-    ret = xmlSchemaAddAttribute(ctxt, schema, (xmlChar *) name);
+    local = xmlSchemaGetNamespace(ctxt, schema, node, BAD_CAST "anyattr", &ns);
+    ret = xmlSchemaAddAttribute(ctxt, schema, BAD_CAST name, ns);
     if (ret == NULL) {
         return (NULL);
     }
-    ret->id = xmlGetProp(node, (const xmlChar *) "id");
-    processContents =
-        xmlGetProp(node, (const xmlChar *) "processContents");
+    ret->id = xmlSchemaGetProp(ctxt, node, "id");
+    processContents = xmlSchemaGetProp(ctxt, node, "processContents");
     if ((processContents == NULL)
         || (xmlStrEqual(processContents, (const xmlChar *) "strict"))) {
         ret->occurs = XML_SCHEMAS_ANYATTR_STRICT;
@@ -1732,8 +1860,6 @@
                        processContents, NULL);
         ret->occurs = XML_SCHEMAS_ANYATTR_STRICT;
     }
-    if (processContents != NULL)
-        xmlFree(processContents);
 
     child = node->children;
     if (IS_SCHEMA(child, "annotation")) {
@@ -1767,15 +1893,15 @@
 xmlSchemaParseAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                         xmlNodePtr node)
 {
-    xmlChar *name, *refNs = NULL, *ref = NULL;
+    const xmlChar *name, *refNs = NULL, *ref = NULL;
     xmlSchemaAttributePtr ret;
     xmlNodePtr child = NULL;
+    char buf[100];
 
     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
         return (NULL);
-    name = xmlGetProp(node, (const xmlChar *) "name");
+    name = xmlSchemaGetProp(ctxt, node, "name");
     if (name == NULL) {
-        char buf[100];
 
         ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
         if (ref == NULL) {
@@ -1784,20 +1910,29 @@
                            "Attribute has no name nor ref\n", NULL, NULL);
             return (NULL);
         }
-        snprintf(buf, 99, "anonattr%d", ctxt->counter++ + 1);
-        name = xmlStrdup((xmlChar *) buf);
+	if (refNs == NULL)
+	    refNs = schema->targetNamespace;
+        snprintf(buf, 99, "anonattr %d", ctxt->counter++ + 1);
+        name = (const xmlChar *) buf;
+	ret = xmlSchemaAddAttribute(ctxt, schema, name, NULL);
+    } else {
+        const xmlChar *local, *ns;
+
+        local = xmlSchemaGetNamespace(ctxt, schema, node, name, &ns);
+	ret = xmlSchemaAddAttribute(ctxt, schema, local, ns);
     }
-    ret = xmlSchemaAddAttribute(ctxt, schema, name);
     if (ret == NULL) {
-        xmlFree(name);
-        if (ref != NULL)
-            xmlFree(ref);
         return (NULL);
     }
-    xmlFree(name);
     ret->ref = ref;
     ret->refNs = refNs;
+    if ((ret->targetNamespace != NULL) &&
+        ((schema->flags & XML_SCHEMAS_QUALIF_ATTR) == 0) &&
+	(xmlStrEqual(ret->targetNamespace, schema->targetNamespace)))
+	ret->flags |= XML_SCHEMAS_ATTR_NSDEFAULT;
     ret->typeName = xmlGetQNameProp(ctxt, node, "type", &(ret->typeNs));
+    if ((ret->typeName != NULL) && (ret->typeNs == NULL))
+        ret->typeNs = schema->targetNamespace;
     ret->node = node;
     child = node->children;
     if (IS_SCHEMA(child, "annotation")) {
@@ -1832,18 +1967,18 @@
 xmlSchemaParseAttributeGroup(xmlSchemaParserCtxtPtr ctxt,
                              xmlSchemaPtr schema, xmlNodePtr node)
 {
-    xmlChar *name, *refNs = NULL, *ref = NULL;
+    const xmlChar *name, *refNs = NULL, *ref = NULL;
     xmlSchemaAttributeGroupPtr ret;
     xmlSchemaAttributePtr last = NULL, attr;
     xmlNodePtr child = NULL;
-    xmlChar *oldcontainer;
+    const xmlChar *oldcontainer;
+    char buf[100];
 
     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
         return (NULL);
     oldcontainer = ctxt->container;
-    name = xmlGetProp(node, (const xmlChar *) "name");
+    name = xmlSchemaGetProp(ctxt, node, "name");
     if (name == NULL) {
-        char buf[100];
 
         ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
         if (ref == NULL) {
@@ -1853,8 +1988,10 @@
                            NULL);
             return (NULL);
         }
-        snprintf(buf, 99, "anonattrgroup%d", ctxt->counter++ + 1);
-        name = xmlStrdup((xmlChar *) buf);
+	if (refNs == NULL)
+	    refNs = schema->targetNamespace;
+        snprintf(buf, 99, "anonattrgroup %d", ctxt->counter++ + 1);
+        name = (const xmlChar *) buf;
         if (name == NULL) {
 	    xmlSchemaPErrMemory(ctxt, "creating attribute group", node);
             return (NULL);
@@ -1862,9 +1999,6 @@
     }
     ret = xmlSchemaAddAttributeGroup(ctxt, schema, name);
     if (ret == NULL) {
-        xmlFree(name);
-        if (ref != NULL)
-            xmlFree(ref);
         return (NULL);
     }
     ret->ref = ref;
@@ -1898,7 +2032,8 @@
         child = child->next;
     }
     if (IS_SCHEMA(child, "anyAttribute")) {
-        TODO child = child->next;
+        TODO
+	child = child->next;
     }
     if (child != NULL) {
         xmlSchemaPErr2(ctxt, node, child,
@@ -1906,9 +2041,7 @@
                        "attribute group %s has unexpected content\n", name,
                        NULL);
     }
-
     ctxt->container = oldcontainer;
-    xmlFree(name);
     return (ret);
 }
 
@@ -1928,17 +2061,18 @@
 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                       xmlNodePtr node, int toplevel)
 {
-    xmlChar *name, *refNs = NULL, *ref = NULL, *namespace, *fixed;
+    const xmlChar *name, *fixed;
+    const xmlChar *refNs = NULL, *ref = NULL;
     xmlSchemaElementPtr ret;
     xmlNodePtr child = NULL;
-    xmlChar *oldcontainer;
+    const xmlChar *oldcontainer;
+    char buf[100];
 
     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
         return (NULL);
     oldcontainer = ctxt->container;
-    name = xmlGetProp(node, (const xmlChar *) "name");
+    name = xmlSchemaGetProp(ctxt, node, "name");
     if (name == NULL) {
-        char buf[100];
 
         ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
         if (ref == NULL) {
@@ -1947,23 +2081,20 @@
                            "Element has no name nor ref\n", NULL, NULL);
             return (NULL);
         }
-        snprintf(buf, 99, "anonelem%d", ctxt->counter++ + 1);
-        name = xmlStrdup((xmlChar *) buf);
+	if (refNs == NULL)
+	    refNs = schema->targetNamespace;
+        snprintf(buf, 99, "anonelem %d", ctxt->counter++ + 1);
+        name = (const xmlChar *) buf;
+	ret = xmlSchemaAddElement(ctxt, schema, name, NULL);
+    } else {
+        const xmlChar *local, *ns;
+
+        local = xmlSchemaGetNamespace(ctxt, schema, node, name, &ns);
+	ret = xmlSchemaAddElement(ctxt, schema, local, ns);
     }
-    namespace = xmlGetProp(node, (const xmlChar *) "targetNamespace");
-    if (namespace == NULL)
-        ret =
-            xmlSchemaAddElement(ctxt, schema, name,
-                                schema->targetNamespace);
-    else
-        ret = xmlSchemaAddElement(ctxt, schema, name, namespace);
-    ret->node = node;
-    if (namespace != NULL)
-        xmlFree(namespace);
+    if (ret != NULL)
+	ret->node = node;
     if (ret == NULL) {
-        xmlFree(name);
-        if (ref != NULL)
-            xmlFree(ref);
         return (NULL);
     }
     ret->type = XML_SCHEMA_TYPE_ELEMENT;
@@ -1979,22 +2110,23 @@
         ret->flags |= XML_SCHEMAS_ELEM_NILLABLE;
     ctxt->container = name;
 
-    ret->id = xmlGetProp(node, BAD_CAST "id");
+    ret->id = xmlSchemaGetProp(ctxt, node, "id");
     ret->namedType =
         xmlGetQNameProp(ctxt, node, "type", &(ret->namedTypeNs));
+    if ((ret->namedType != NULL) && (ret->namedTypeNs == NULL))
+        ret->namedTypeNs = schema->targetNamespace;
     ret->substGroup =
         xmlGetQNameProp(ctxt, node, "substitutionGroup",
                         &(ret->substGroupNs));
-    fixed = xmlGetProp(node, BAD_CAST "fixed");
+    fixed = xmlSchemaGetProp(ctxt, node, "fixed");
     ret->minOccurs = xmlGetMinOccurs(ctxt, node);
     ret->maxOccurs = xmlGetMaxOccurs(ctxt, node);
 
-    ret->value = xmlGetProp(node, BAD_CAST "default");
+    ret->value = xmlSchemaGetProp(ctxt, node, "default");
     if ((ret->value != NULL) && (fixed != NULL)) {
         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_ELEM_DEFAULT_FIXED,
                        "Element %s has both default and fixed\n",
 		       ret->name, NULL);
-        xmlFree(fixed);
     } else if (fixed != NULL) {
         ret->flags |= XML_SCHEMAS_ELEM_FIXED;
         ret->value = fixed;
@@ -2022,7 +2154,6 @@
     }
 
     ctxt->container = oldcontainer;
-    xmlFree(name);
     return (ret);
 }
 
@@ -2051,13 +2182,13 @@
 
 
     snprintf((char *) name, 30, "union %d", ctxt->counter++ + 1);
-    type = xmlSchemaAddType(ctxt, schema, name);
+    type = xmlSchemaAddType(ctxt, schema, name, NULL);
     if (type == NULL)
         return (NULL);
     type->node = node;
     type->type = XML_SCHEMA_TYPE_LIST;
-    type->id = xmlGetProp(node, BAD_CAST "id");
-    type->ref = xmlGetProp(node, BAD_CAST "memberTypes");
+    type->id = xmlSchemaGetProp(ctxt, node, "id");
+    type->ref = xmlSchemaGetProp(ctxt, node, "memberTypes");
 
     child = node->children;
     if (IS_SCHEMA(child, "annotation")) {
@@ -2111,13 +2242,15 @@
         return (NULL);
 
     snprintf((char *) name, 30, "list %d", ctxt->counter++ + 1);
-    type = xmlSchemaAddType(ctxt, schema, name);
+    type = xmlSchemaAddType(ctxt, schema, name, NULL);
     if (type == NULL)
         return (NULL);
     type->node = node;
     type->type = XML_SCHEMA_TYPE_LIST;
-    type->id = xmlGetProp(node, BAD_CAST "id");
+    type->id = xmlSchemaGetProp(ctxt, node, "id");
     type->ref = xmlGetQNameProp(ctxt, node, "ref", &(type->refNs));
+    if ((type->ref != NULL) && (type->refNs == NULL))
+	type->refNs = schema->targetNamespace;
 
     child = node->children;
     if (IS_SCHEMA(child, "annotation")) {
@@ -2157,31 +2290,29 @@
 {
     xmlSchemaTypePtr type, subtype;
     xmlNodePtr child = NULL;
-    xmlChar *name;
+    const xmlChar *name;
 
     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
         return (NULL);
 
 
-    name = xmlGetProp(node, (const xmlChar *) "name");
+    name = xmlSchemaGetProp(ctxt, node, "name");
     if (name == NULL) {
         char buf[100];
 
-        snprintf(buf, 99, "simpletype%d", ctxt->counter++ + 1);
-        name = xmlStrdup((xmlChar *) buf);
+        snprintf(buf, 99, "simpletype %d", ctxt->counter++ + 1);
+	type = xmlSchemaAddType(ctxt, schema, (const xmlChar *)buf, NULL);
+    } else {
+	const xmlChar *local, *ns;
+
+        local = xmlSchemaGetNamespace(ctxt, schema, node, name, &ns);
+	type = xmlSchemaAddType(ctxt, schema, local, ns);
     }
-    if (name == NULL) {
-        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_SIMPLETYPE_NONAME,
-                       "simpleType has no name\n", NULL, NULL);
-        return (NULL);
-    }
-    type = xmlSchemaAddType(ctxt, schema, name);
-    xmlFree(name);
     if (type == NULL)
         return (NULL);
     type->node = node;
     type->type = XML_SCHEMA_TYPE_SIMPLE;
-    type->id = xmlGetProp(node, BAD_CAST "id");
+    type->id = xmlSchemaGetProp(ctxt, node, "id");
 
     child = node->children;
     if (IS_SCHEMA(child, "annotation")) {
@@ -2232,15 +2363,16 @@
 {
     xmlSchemaTypePtr type, subtype;
     xmlNodePtr child = NULL;
-    xmlChar *name, *ref = NULL, *refNs = NULL;
+    const xmlChar *name;
+    const xmlChar *ref = NULL, *refNs = NULL;
+    char buf[100];
 
     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
         return (NULL);
 
 
-    name = xmlGetProp(node, (const xmlChar *) "name");
+    name = xmlSchemaGetProp(ctxt, node, "name");
     if (name == NULL) {
-        char buf[100];
 
         ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
         if (ref == NULL) {
@@ -2249,17 +2381,18 @@
                            "Group has no name nor ref\n", NULL, NULL);
             return (NULL);
         }
-        snprintf(buf, 99, "anongroup%d", ctxt->counter++ + 1);
-        name = xmlStrdup((xmlChar *) buf);
+	if (refNs == NULL)
+	    refNs = schema->targetNamespace;
+        snprintf(buf, 99, "anongroup %d", ctxt->counter++ + 1);
+        name = (const 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");
+    type->id = xmlSchemaGetProp(ctxt, node, "id");
     type->ref = ref;
     type->refNs = refNs;
     type->minOccurs = xmlGetMinOccurs(ctxt, node);
@@ -2319,12 +2452,12 @@
 
 
     snprintf((char *) name, 30, "all%d", ctxt->counter++ + 1);
-    type = xmlSchemaAddType(ctxt, schema, name);
+    type = xmlSchemaAddType(ctxt, schema, name, NULL);
     if (type == NULL)
         return (NULL);
     type->node = node;
     type->type = XML_SCHEMA_TYPE_ALL;
-    type->id = xmlGetProp(node, BAD_CAST "id");
+    type->id = xmlSchemaGetProp(ctxt, node, "id");
     type->minOccurs = xmlGetMinOccurs(ctxt, node);
     type->maxOccurs = xmlGetMaxOccurs(ctxt, node);
 
@@ -2393,7 +2526,7 @@
     }
 
     memset(import, 0, sizeof(xmlSchemaImport));
-    import->schemaLocation = xmlStrdup(schemaLocation);
+    import->schemaLocation = xmlDictLookup(ctxt->dict, schemaLocation, -1);
     import->schema = xmlSchemaParse(newctxt);
 
     if (import->schema == NULL) {
@@ -2432,8 +2565,8 @@
 {
     xmlNodePtr child = NULL;
     xmlSchemaImportPtr import = NULL;
-    xmlChar *namespace;
-    xmlChar *schemaLocation;
+    const xmlChar *namespace;
+    const xmlChar *schemaLocation;
     const xmlChar *previous;
     xmlURIPtr check;
 
@@ -2441,7 +2574,7 @@
     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
         return (-1);
 
-    namespace = xmlGetProp(node, BAD_CAST "namespace");
+    namespace = xmlSchemaGetProp(ctxt, node, "namespace");
     if (namespace != NULL) {
         check = xmlParseURI((const char *) namespace);
         if (check == NULL) {
@@ -2449,13 +2582,12 @@
                            XML_SCHEMAP_IMPORT_NAMESPACE_NOT_URI,
                            "Import namespace attribute is not an URI: %s\n",
                            namespace, NULL);
-            xmlFree(namespace);
             return (-1);
         } else {
             xmlFreeURI(check);
         }
     }
-    schemaLocation = xmlGetProp(node, BAD_CAST "schemaLocation");
+    schemaLocation = xmlSchemaGetProp(ctxt, node, "schemaLocation");
     if (schemaLocation != NULL) {
         xmlChar *base = NULL;
         xmlChar *URI = NULL;
@@ -2465,9 +2597,6 @@
                            XML_SCHEMAP_IMPORT_SCHEMA_NOT_URI,
                            "Import schemaLocation attribute is not an URI: %s\n",
                            schemaLocation, NULL);
-            if (namespace != NULL)
-                xmlFree(namespace);
-            xmlFree(schemaLocation);
             return (-1);
         } else {
             xmlFreeURI(check);
@@ -2477,11 +2606,11 @@
 	    URI = xmlBuildURI(schemaLocation, node->doc->URL);
 	} else {
 	    URI = xmlBuildURI(schemaLocation, base);
+	    xmlFree(base);
 	}
-	if (base != NULL) xmlFree(base);
 	if (URI != NULL) {
-	    xmlFree(schemaLocation);
-	    schemaLocation = URI;
+	    schemaLocation = xmlDictLookup(ctxt->dict, URI, -1);
+	    xmlFree(URI);
 	}
     }
     if (schema->schemasImports == NULL) {
@@ -2491,10 +2620,6 @@
                            XML_SCHEMAP_FAILED_BUILD_IMPORT,
                            "Internal: failed to build import table\n",
                            NULL, NULL);
-            if (namespace != NULL)
-                xmlFree(namespace);
-            if (schemaLocation != NULL)
-                xmlFree(schemaLocation);
             return (-1);
         }
     }
@@ -2517,17 +2642,12 @@
             } 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,
                                 import);
             }
-	    xmlFree(schemaLocation);
         }
     } else {
         import = xmlHashLookup(schema->schemasImports, namespace);
@@ -2547,20 +2667,13 @@
             } else {
 	        import = xmlSchemaImportSchema(ctxt, schemaLocation);
 		if (import == NULL) {
-		    if (schemaLocation != NULL)
-			xmlFree(schemaLocation);
-		    if (namespace != NULL)
-			xmlFree(namespace);
 		    return (-1);
 		}
                 xmlHashAddEntry(schema->schemasImports,
                                 namespace, import);
             }
         }
-	xmlFree(namespace);
     }
-    if (schemaLocation != NULL)
-	xmlFree(schemaLocation);
 
     child = node->children;
     while (IS_SCHEMA(child, "annotation")) {
@@ -2602,12 +2715,12 @@
 
 
     snprintf((char *) name, 30, "choice %d", ctxt->counter++ + 1);
-    type = xmlSchemaAddType(ctxt, schema, name);
+    type = xmlSchemaAddType(ctxt, schema, name, NULL);
     if (type == NULL)
         return (NULL);
     type->node = node;
     type->type = XML_SCHEMA_TYPE_CHOICE;
-    type->id = xmlGetProp(node, BAD_CAST "id");
+    type->id = xmlSchemaGetProp(ctxt, node, "id");
     type->minOccurs = xmlGetMinOccurs(ctxt, node);
     type->maxOccurs = xmlGetMaxOccurs(ctxt, node);
 
@@ -2680,12 +2793,12 @@
 
 
     snprintf((char *) name, 30, "sequence %d", ctxt->counter++ + 1);
-    type = xmlSchemaAddType(ctxt, schema, name);
+    type = xmlSchemaAddType(ctxt, schema, name, NULL);
     if (type == NULL)
         return (NULL);
     type->node = node;
     type->type = XML_SCHEMA_TYPE_SEQUENCE;
-    type->id = xmlGetProp(node, BAD_CAST "id");
+    type->id = xmlSchemaGetProp(ctxt, node, "id");
     type->minOccurs = xmlGetMinOccurs(ctxt, node);
     type->maxOccurs = xmlGetMaxOccurs(ctxt, node);
 
@@ -2754,7 +2867,7 @@
     xmlSchemaFacetPtr facet, lastfacet = NULL;
     xmlNodePtr child = NULL;
     xmlChar name[30];
-    xmlChar *oldcontainer;
+    const xmlChar *oldcontainer;
 
     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
         return (NULL);
@@ -2762,12 +2875,12 @@
     oldcontainer = ctxt->container;
 
     snprintf((char *) name, 30, "restriction %d", ctxt->counter++ + 1);
-    type = xmlSchemaAddType(ctxt, schema, name);
+    type = xmlSchemaAddType(ctxt, schema, name, NULL);
     if (type == NULL)
         return (NULL);
     type->node = node;
     type->type = XML_SCHEMA_TYPE_RESTRICTION;
-    type->id = xmlGetProp(node, BAD_CAST "id");
+    type->id = xmlSchemaGetProp(ctxt, node, "id");
     type->base = xmlGetQNameProp(ctxt, node, "base", &(type->baseNs));
     if ((!simple) && (type->base == NULL)) {
         xmlSchemaPErr2(ctxt, node, child,
@@ -2867,7 +2980,7 @@
     xmlSchemaTypePtr type, subtype;
     xmlNodePtr child = NULL;
     xmlChar name[30];
-    xmlChar *oldcontainer;
+    const xmlChar *oldcontainer;
 
     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
         return (NULL);
@@ -2875,12 +2988,12 @@
     oldcontainer = ctxt->container;
 
     snprintf((char *) name, 30, "extension %d", ctxt->counter++ + 1);
-    type = xmlSchemaAddType(ctxt, schema, name);
+    type = xmlSchemaAddType(ctxt, schema, name, NULL);
     if (type == NULL)
         return (NULL);
     type->node = node;
     type->type = XML_SCHEMA_TYPE_EXTENSION;
-    type->id = xmlGetProp(node, BAD_CAST "id");
+    type->id = xmlSchemaGetProp(ctxt, node, "id");
     ctxt->container = name;
 
     type->base = xmlGetQNameProp(ctxt, node, "base", &(type->baseNs));
@@ -2945,12 +3058,12 @@
 
 
     snprintf((char *) name, 30, "complexContent %d", ctxt->counter++ + 1);
-    type = xmlSchemaAddType(ctxt, schema, name);
+    type = xmlSchemaAddType(ctxt, schema, name, NULL);
     if (type == NULL)
         return (NULL);
     type->node = node;
     type->type = XML_SCHEMA_TYPE_SIMPLE_CONTENT;
-    type->id = xmlGetProp(node, BAD_CAST "id");
+    type->id = xmlSchemaGetProp(ctxt, node, "id");
 
     child = node->children;
     if (IS_SCHEMA(child, "annotation")) {
@@ -3001,12 +3114,12 @@
 
 
     snprintf((char *) name, 30, "complexContent %d", ctxt->counter++ + 1);
-    type = xmlSchemaAddType(ctxt, schema, name);
+    type = xmlSchemaAddType(ctxt, schema, name, NULL);
     if (type == NULL)
         return (NULL);
     type->node = node;
     type->type = XML_SCHEMA_TYPE_COMPLEX_CONTENT;
-    type->id = xmlGetProp(node, BAD_CAST "id");
+    type->id = xmlSchemaGetProp(ctxt, node, "id");
 
     child = node->children;
     if (IS_SCHEMA(child, "annotation")) {
@@ -3050,34 +3163,32 @@
 {
     xmlSchemaTypePtr type, subtype;
     xmlNodePtr child = NULL;
-    xmlChar *name;
-    xmlChar *oldcontainer;
+    const xmlChar *name;
+    const xmlChar *oldcontainer;
+    char buf[100];
 
     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
         return (NULL);
 
     oldcontainer = ctxt->container;
-    name = xmlGetProp(node, (const xmlChar *) "name");
+    name = xmlSchemaGetProp(ctxt, node, "name");
     if (name == NULL) {
-        char buf[100];
 
-        snprintf(buf, 99, "anontype%d", ctxt->counter++ + 1);
-        name = xmlStrdup((xmlChar *) buf);
+        snprintf(buf, 99, "anontype %d", ctxt->counter++ + 1);
+	name = (const xmlChar *)buf;
+	type = xmlSchemaAddType(ctxt, schema, name, NULL);
+    } else {
+	const xmlChar *local, *ns;
+
+        local = xmlSchemaGetNamespace(ctxt, schema, node, name, &ns);
+	type = xmlSchemaAddType(ctxt, schema, local, ns);
     }
-    if (name == NULL) {
-        xmlSchemaPErr2(ctxt, node, child,
-                       XML_SCHEMAP_COMPLEXTYPE_NONAME_NOREF,
-                       "complexType has no name\n", NULL, NULL);
-        return (NULL);
-    }
-    type = xmlSchemaAddType(ctxt, schema, name);
     if (type == NULL) {
-        xmlFree(name);
         return (NULL);
     }
     type->node = node;
     type->type = XML_SCHEMA_TYPE_COMPLEX;
-    type->id = xmlGetProp(node, BAD_CAST "id");
+    type->id = xmlSchemaGetProp(ctxt, node, "id");
     ctxt->container = name;
 
     child = node->children;
@@ -3118,7 +3229,6 @@
                        type->name, NULL);
     }
     ctxt->container = oldcontainer;
-    xmlFree(name);
     return (type);
 }
 
@@ -3140,7 +3250,7 @@
     xmlSchemaPtr schema = NULL;
     xmlSchemaAnnotPtr annot;
     xmlNodePtr child = NULL;
-    xmlChar *val;
+    const xmlChar *val;
     int nberrors;
 
     if ((ctxt == NULL) || (node == NULL))
@@ -3152,11 +3262,15 @@
         schema = xmlSchemaNewSchema(ctxt);
         if (schema == NULL)
             return (NULL);
-        schema->targetNamespace =
-            xmlGetProp(node, BAD_CAST "targetNamespace");
-        schema->id = xmlGetProp(node, BAD_CAST "id");
-        schema->version = xmlGetProp(node, BAD_CAST "version");
-        val = xmlGetProp(node, BAD_CAST "elementFormDefault");
+	val = xmlSchemaGetProp(ctxt, node, "targetNamespace");
+	if (val != NULL) {
+	    schema->targetNamespace = xmlDictLookup(ctxt->dict, val, -1);
+	} else {
+	    schema->targetNamespace = NULL;
+	}
+        schema->id = xmlSchemaGetProp(ctxt, node, "id");
+        schema->version = xmlSchemaGetProp(ctxt, node, "version");
+        val = xmlSchemaGetProp(ctxt, node, "elementFormDefault");
         if (val != NULL) {
             if (xmlStrEqual(val, BAD_CAST "qualified"))
                 schema->flags |= XML_SCHEMAS_QUALIF_ELEM;
@@ -3166,9 +3280,10 @@
                                "Invalid value %s for elementFormDefault\n",
                                val, NULL);
             }
-            xmlFree(val);
-        }
-        val = xmlGetProp(node, BAD_CAST "attributeFormDefault");
+        } else {
+	    schema->flags |= XML_SCHEMAS_QUALIF_ELEM;
+	}
+        val = xmlSchemaGetProp(ctxt, node, "attributeFormDefault");
         if (val != NULL) {
             if (xmlStrEqual(val, BAD_CAST "qualified"))
                 schema->flags |= XML_SCHEMAS_QUALIF_ATTR;
@@ -3178,8 +3293,7 @@
                                "Invalid value %s for attributeFormDefault\n",
                                val, NULL);
             }
-            xmlFree(val);
-        }
+        } 
 
         child = node->children;
         while ((IS_SCHEMA(child, "include")) ||
@@ -3290,7 +3404,8 @@
         return (NULL);
     }
     memset(ret, 0, sizeof(xmlSchemaParserCtxt));
-    ret->URL = xmlStrdup((const xmlChar *) URL);
+    ret->dict = xmlDictCreate();
+    ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
     return (ret);
 }
 
@@ -3364,10 +3479,9 @@
 {
     if (ctxt == NULL)
         return;
-    if (ctxt->URL != NULL)
-        xmlFree(ctxt->URL);
     if (ctxt->doc != NULL)
         xmlFreeDoc(ctxt->doc);
+    xmlDictFree(ctxt->dict);
     xmlFree(ctxt);
 }
 
@@ -3769,7 +3883,8 @@
     }
     if (elem->subtypes->type != XML_SCHEMA_TYPE_COMPLEX)
         return;
-    if (elem->subtypes->contentType == XML_SCHEMA_CONTENT_BASIC)
+    if ((elem->subtypes->contentType == XML_SCHEMA_CONTENT_BASIC) ||
+        (elem->subtypes->contentType == XML_SCHEMA_CONTENT_SIMPLE))
         return;
 
 #ifdef DEBUG_CONTENT
@@ -3832,8 +3947,7 @@
                           name, NULL);
             return;
         }
-        elemDecl = xmlHashLookup2(ctxt->schema->elemDecl,
-                                  elem->ref, elem->refNs);
+        elemDecl = xmlSchemaGetElem(ctxt->schema, elem->ref, elem->refNs);
 
         if (elemDecl == NULL) {
             xmlSchemaPErr(ctxt, elem->node, XML_SCHEMAP_UNKNOWN_REF,
@@ -3906,9 +4020,13 @@
                         }
                         typeDecl->baseType = baseType;
                     }
-                    if (typeDecl->subtypes == NULL)
-                        /* 1.1.1 */
-                        typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
+		    if (typeDecl->subtypes == NULL)
+			if (typeDecl->baseType != NULL)
+			    typeDecl->contentType =
+			             typeDecl->baseType->contentType;
+			else 
+                            /* 1.1.1 */
+                            typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
                     else if ((typeDecl->subtypes->subtypes == NULL) &&
                              ((typeDecl->subtypes->type ==
                                XML_SCHEMA_TYPE_ALL)
@@ -4055,6 +4173,8 @@
             case XML_SCHEMA_FACET_MAXLENGTH:
             case XML_SCHEMA_FACET_MINLENGTH:
                 typeDecl->contentType = XML_SCHEMA_CONTENT_SIMPLE;
+		if (typeDecl->subtypes != NULL)
+		    xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL);
                 break;
         }
     }
@@ -4608,7 +4728,7 @@
 static int
 xmlSchemaValidateFacets(xmlSchemaValidCtxtPtr ctxt,
                         xmlSchemaTypePtr base,
-                        xmlSchemaFacetPtr facets, xmlChar * value)
+                        xmlSchemaFacetPtr facets, const xmlChar * value)
 {
     int ret = 0;
     int tmp = 0;
@@ -4661,7 +4781,7 @@
  */
 static int
 xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
-                             xmlSchemaTypePtr type, xmlChar * value)
+                             xmlSchemaTypePtr type, const xmlChar * value)
 {
     int ret = 0;
 
@@ -4691,8 +4811,9 @@
         if (base != NULL) {
             ret = xmlSchemaValidateSimpleValue(ctxt, base, value);
         } else if (type->subtypes != NULL) {
-
+	    TODO
         }
+
         /*
          * Do not validate facets when working on building the Schemas
          */
@@ -4712,7 +4833,8 @@
         TODO}
     } else if (type->type == XML_SCHEMA_TYPE_LIST) {
         xmlSchemaTypePtr base;
-        xmlChar *cur, *end, tmp;
+        const xmlChar *cur, *end;
+	xmlChar *tmp;
         int ret2;
 
         base = type->subtypes;
@@ -4731,16 +4853,16 @@
                 end++;
             if (end == cur)
                 break;
-            tmp = *end;
-            *end = 0;
-            ret2 = xmlSchemaValidateSimpleValue(ctxt, base, cur);
+            tmp = xmlStrndup(cur, end - cur);
+            ret2 = xmlSchemaValidateSimpleValue(ctxt, base, tmp);
+	    xmlFree(tmp);
             if (ret2 != 0)
                 ret = 1;
-            *end = tmp;
             cur = end;
         } while (*cur != 0);
     } else {
-    TODO}
+        TODO
+    }
     return (ret);
 }
 
@@ -4871,8 +4993,13 @@
                 }
                 break;
             }
+        case XML_SCHEMA_TYPE_EXTENSION:{
+	        TODO
+                break;
+            }
         default:
-    TODO}
+	    TODO
+    }
     if (value != NULL)
         xmlFree(value);
 
@@ -5278,7 +5405,8 @@
 
     switch (type->contentType) {
         case XML_SCHEMA_CONTENT_EMPTY:
-            if (child != NULL) {
+	    if (type->baseType != NULL) {
+	    } else if (child != NULL) {
 		xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_NOTEMPTY, "Element %s is supposed to be empty\n", node->name, NULL);
             }
             if (type->attributes != NULL) {
@@ -5334,6 +5462,22 @@
                 ctxt->type = type;
                 break;
             }
+        case XML_SCHEMA_CONTENT_SIMPLE:{
+                if (type->subtypes != NULL) {
+                    ctxt->type = type->subtypes;
+                    xmlSchemaValidateComplexType(ctxt, node);
+                }
+                if (type->baseType != NULL) {
+                    ctxt->type = type->baseType;
+                    xmlSchemaValidateComplexType(ctxt, node);
+                }
+                if (type->attributes != NULL) {
+                    xmlSchemaValidateAttributes(ctxt, node,
+                                                type->attributes);
+                }
+                ctxt->type = type;
+                break;
+	}
         default:
             TODO xmlGenericError(xmlGenericErrorContext,
                                  "unimplemented content type %d\n",
@@ -5577,10 +5721,23 @@
                 if (!xmlStrEqual(attr->name, attributes->name))
                     continue;
                 /*
-                 * TODO: handle the mess about namespaces here.
+                 * handle the namespaces checks here
                  */
-                if ((attr->ns != NULL) /* || (attributes->ns != NULL) */ ) {
-                TODO}
+                if (attr->ns == NULL) {
+		    /*
+		     * accept an unqualified attribute only if the declaration
+		     * is unqualified or if the schemas allowed it.
+		     */
+		    if ((attributes->targetNamespace != NULL) &&
+		        ((attributes->flags & XML_SCHEMAS_ATTR_NSDEFAULT) == 0))
+		        continue;
+		} else {
+		    if (attributes->targetNamespace == NULL)
+		        continue;
+		    if (!xmlStrEqual(attributes->targetNamespace,
+		                     attr->ns->href))
+			continue;
+		}
             }
             ctxt->cur = (xmlNodePtr) attributes;
             if (attributes->subtypes == NULL) {
@@ -5620,12 +5777,24 @@
     xmlSchemaElementPtr elemDecl;
     int ret, attrBase;
 
-    if (elem->ns != NULL)
+    if (elem->ns != NULL) {
         elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
                                   elem->name, elem->ns->href, NULL);
-    else
+    } else {
         elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
                                   elem->name, NULL, NULL);
+    }
+    /*
+     * special case whe elementFormDefault is unqualified for top-level elem.
+     */
+    if ((elemDecl == NULL) && (elem->ns != NULL) &&
+        (elem->parent != NULL) && (elem->parent->type != XML_ELEMENT_NODE) &&
+        (xmlStrEqual(ctxt->schema->targetNamespace, elem->ns->href)) &&
+	((ctxt->schema->flags & XML_SCHEMAS_QUALIF_ELEM) == 0)) {
+        elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
+                                  elem->name, NULL, NULL);
+    }
+
     /*
      * 3.3.4 : 1
      */
@@ -5713,6 +5882,16 @@
     else
         elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
                                   root->name, NULL, NULL);
+    /*
+     * special case whe elementFormDefault is unqualified for top-level elem.
+     */
+    if ((elemDecl == NULL) && (root->ns != NULL) &&
+        (xmlStrEqual(ctxt->schema->targetNamespace, root->ns->href)) &&
+	((ctxt->schema->flags & XML_SCHEMAS_QUALIF_ELEM) == 0)) {
+        elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
+                                  root->name, NULL, NULL);
+    }
+
     if (elemDecl == NULL) {
         xmlSchemaVErr(ctxt, root, XML_SCHEMAS_ERR_UNDECLAREDELEM, "Element %s not declared\n", root->name, NULL);
     } else if ((elemDecl->flags & XML_SCHEMAS_ELEM_TOPLEVEL) == 0) {