move the TODO as comments as the function while not finished are usable

* xmlsave.c: move the TODO as comments as the function while not
  finished are usable as-is
* xmlschemas.c include/libxml/xmlerror.h: patch from Kasimier Buchcik
  implementing union
* test/schemas/union_0_0.x* result/schemas/union_0_0*: added example
* python/Makefile.am: applied fix from Mike Hommey
Daniel
diff --git a/xmlschemas.c b/xmlschemas.c
index 99bf02b..be7b6ae 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -2279,7 +2279,7 @@
     if (type == NULL)
         return (NULL);
     type->node = node;
-    type->type = XML_SCHEMA_TYPE_LIST;
+    type->type = XML_SCHEMA_TYPE_UNION;
     type->id = xmlSchemaGetProp(ctxt, node, "id");
     type->ref = xmlSchemaGetProp(ctxt, node, "memberTypes");
 
@@ -4358,6 +4358,57 @@
     }
 }
 
+static void
+xmlSchemaParseUnionRefCheck(xmlSchemaTypePtr typeDecl,
+                   xmlSchemaParserCtxtPtr ctxt)
+{
+    const xmlChar *cur, *end, *prefix, *ncName, *namespace;
+    xmlChar *tmp;
+    xmlSchemaTypePtr subtype;
+    xmlNsPtr ns;
+    int len;
+
+     if ((typeDecl->type != XML_SCHEMA_TYPE_UNION) || (typeDecl->ref == NULL))
+        return;
+
+    cur = typeDecl->ref;
+    do {
+        while (IS_BLANK_CH(*cur))
+            cur++;
+        end = cur;
+        while ((*end != 0) && (!(IS_BLANK_CH(*end))))
+            end++;
+        if (end == cur)
+            break;
+        tmp = xmlStrndup(cur, end - cur);
+        ncName = xmlSplitQName3(tmp, &len);
+        if (ncName != NULL) {
+            prefix = xmlDictLookup(ctxt->dict, tmp, len);
+        } else {
+            prefix = NULL;
+            ncName = tmp;
+        }
+        ns = xmlSearchNs(typeDecl->node->doc, typeDecl->node, prefix);
+        if (ns == NULL) {
+            xmlSchemaPErr(ctxt, typeDecl->node, XML_SCHEMAP_PREFIX_UNDEFINED,
+                  "Union %s: the namespace of member type %s is undefined\n",
+                  typeDecl->name, (const char *) tmp);                        
+        } else {
+            namespace = xmlDictLookup(ctxt->dict, ns->href, -1);
+        }
+        /* Lookup the referenced type */
+        subtype = xmlSchemaGetType(ctxt->schema, ncName, namespace);
+        if (subtype == NULL) {
+            xmlSchemaPErr(ctxt, typeDecl->node, XML_SCHEMAP_UNKNOWN_MEMBER_TYPE,
+                       "Union %s references an unknown member type >%s<\n",
+                       typeDecl->name,  (const char *) tmp);
+        } 
+	 xmlFree(tmp);
+        cur = end;
+    } while (*cur != 0);
+    
+}
+
 /**
  * xmlSchemaTypeFixup:
  * @typeDecl:  the schema type definition
@@ -4553,6 +4604,7 @@
             case XML_SCHEMA_TYPE_NOTATION:
             case XML_SCHEMA_TYPE_LIST:
             case XML_SCHEMA_TYPE_UNION:
+                xmlSchemaParseUnionRefCheck(typeDecl, ctxt);
             case XML_SCHEMA_FACET_MININCLUSIVE:
             case XML_SCHEMA_FACET_MINEXCLUSIVE:
             case XML_SCHEMA_FACET_MAXINCLUSIVE:
@@ -5077,6 +5129,28 @@
                         xmlSchemaTypePtr base,
                         xmlSchemaFacetPtr facets, const xmlChar * value)
 {
+    return(xmlSchemaValidateFacetsInternal(ctxt, base, facets, value, 1));
+}
+
+/**
+ * xmlSchemaValidateFacetsInternal:
+ * @ctxt:  a schema validation context
+ * @base:  the base type
+ * @facets:  the list of facets to check
+ * @value:  the lexical repr of the value to validate
+ * @val:  the precomputed value
+ * @fireErrors:  if 0, only internal errors will be fired; otherwise all errors will be fired.
+ *
+ * Check a value against all facet conditions
+ *
+ * Returns 0 if the element is schemas valid, a positive error code
+ *     number otherwise and -1 in case of internal or API error.
+ */
+static int
+xmlSchemaValidateFacetsInternal(xmlSchemaValidCtxtPtr ctxt,
+                        xmlSchemaTypePtr base,
+                        xmlSchemaFacetPtr facets, const xmlChar * value, int fireErrors)
+{
     int ret = 0;
     int tmp = 0;
     xmlSchemaTypeType type;
@@ -5101,7 +5175,8 @@
 
         if (tmp != 0) {
             ret = tmp;
-            xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_FACET, "Failed to validate type with facet %s\n", (const xmlChar *) xmlSchemaFacetTypeToString(type), NULL);
+            if (fireErrors)
+                xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_FACET, "Failed to validate type with facet %s\n", (const xmlChar *) xmlSchemaFacetTypeToString(type), NULL);
         }
         if (facet != NULL)
             facet = facet->next;
@@ -5116,6 +5191,76 @@
  ************************************************************************/
 
 /**
+ * xmlSchemaValidateSimpleValueUnion:
+ * @ctxt:  a schema validation context
+ * @type:  the type declaration
+ * @value:  the value to validate
+ *
+ * Validates a value against a union.
+ *
+ * Returns 0 if the value is valid, a positive error code
+ *     number otherwise and -1 in case of internal or API error.
+ */
+static int
+xmlSchemaValidateSimpleValueUnion(xmlSchemaValidCtxtPtr ctxt,
+                             xmlSchemaTypePtr type, const xmlChar * value)
+{
+    int ret = 0;
+    const xmlChar *cur, *end, *prefix, *ncName;
+    xmlChar *tmp;
+    xmlSchemaTypePtr subtype;
+    xmlNsPtr ns;
+    int len;
+   
+
+    /* Process referenced memberTypes. */
+    cur = type->ref;
+    do {
+        while (IS_BLANK_CH(*cur))
+            cur++;
+        end = cur;
+        while ((*end != 0) && (!(IS_BLANK_CH(*end))))
+            end++;
+        if (end == cur)
+            break;
+        tmp = xmlStrndup(cur, end - cur);
+         ncName = xmlSplitQName3(tmp, &len);
+        if (ncName != NULL) {
+            prefix = xmlStrndup(tmp, len);
+            /* prefix = xmlDictLookup(ctxt->doc->dict, tmp, len); */
+        } else {
+            prefix = NULL;
+            ncName = tmp;
+        }
+        /* We won't do additional checks here, since they have been performed during parsing. */
+        ns = xmlSearchNs(type->node->doc, type->node, prefix);
+        /* namespace = xmlDictLookup(ctxt->doc->dict, ns->href, -1); */
+        subtype = xmlSchemaGetType(ctxt->schema, ncName, ns->href);
+	if (tmp != NULL)
+	    xmlFree(tmp);
+	if (prefix != NULL)
+	    xmlFree(prefix);
+        ret = xmlSchemaValidateSimpleValueInternal(ctxt, subtype, value, 0);
+        if ((ret == 0) || (ret == -1)) {
+            return (ret);
+        }
+        cur = end;
+    } while (*cur != 0);
+
+    if (type->subtypes != NULL) {
+        subtype = type->subtypes;
+        do {
+            ret = xmlSchemaValidateSimpleValueInternal(ctxt, subtype, value, 0);
+            if ((ret == 0) || (ret == -1)) {
+                return (ret);
+            }
+            subtype = subtype->next;
+        } while (subtype != NULL);
+    }
+    return (ret);
+}
+
+/**
  * xmlSchemaValidateSimpleValue:
  * @ctxt:  a schema validation context
  * @type:  the type declaration
@@ -5130,6 +5275,25 @@
 xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
                              xmlSchemaTypePtr type, const xmlChar * value)
 {
+  return (xmlSchemaValidateSimpleValueInternal(ctxt, type, value, 1));
+}
+
+/**
+ * xmlSchemaValidateSimpleValue:
+ * @ctxt:  a schema validation context
+ * @type:  the type declaration
+ * @value:  the value to validate
+ * @fireErrors:  if 0, only internal errors will be fired; otherwise all errors will be fired.
+ *
+ * Validate a value against a simple type
+ *
+ * Returns 0 if the value is valid, a positive error code
+ *     number otherwise and -1 in case of internal or API error.
+ */
+static int
+xmlSchemaValidateSimpleValueInternal(xmlSchemaValidCtxtPtr ctxt,
+                             xmlSchemaTypePtr type, const xmlChar * value, int fireErrors)
+{
     int ret = 0;
 
     /*
@@ -5147,7 +5311,7 @@
         }
         ret = xmlSchemaValPredefTypeNode(type, value, &(ctxt->value),
                                          ctxt->cur);
-        if (ret != 0) {
+        if ((fireErrors) && (ret != 0)) {
             xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_VALUE, "Failed to validate basic type %s\n", type->name, NULL);
         }
     } else if (type->type == XML_SCHEMA_TYPE_RESTRICTION) {
@@ -5156,7 +5320,7 @@
 
         base = type->baseType;
         if (base != NULL) {
-            ret = xmlSchemaValidateSimpleValue(ctxt, base, value);
+            ret = xmlSchemaValidateSimpleValueInternal(ctxt, base, value, fireErrors);
         } else if (type->subtypes != NULL) {
 	    TODO
         }
@@ -5168,7 +5332,7 @@
         if (ctxt->schema != NULL) {
             if (ret == 0) {
                 facet = type->facets;
-                ret = xmlSchemaValidateFacets(ctxt, base, facet, value);
+                ret = xmlSchemaValidateFacetsInternal(ctxt, base, facet, value, fireErrors);
             }
         }
     } else if (type->type == XML_SCHEMA_TYPE_SIMPLE) {
@@ -5176,7 +5340,7 @@
 
         base = type->subtypes;
         if (base != NULL) {
-            ret = xmlSchemaValidateSimpleValue(ctxt, base, value);
+            ret = xmlSchemaValidateSimpleValueInternal(ctxt, base, value, fireErrors);
         } else {
         TODO}
     } else if (type->type == XML_SCHEMA_TYPE_LIST) {
@@ -5202,12 +5366,17 @@
             if (end == cur)
                 break;
             tmp = xmlStrndup(cur, end - cur);
-            ret2 = xmlSchemaValidateSimpleValue(ctxt, base, tmp);
+            ret2 = xmlSchemaValidateSimpleValueInternal(ctxt, base, tmp, fireErrors);
 	    xmlFree(tmp);
             if (ret2 != 0)
                 ret = 1;
             cur = end;
         } while (*cur != 0);
+    }  else if (type->type == XML_SCHEMA_TYPE_UNION) {
+        ret = xmlSchemaValidateSimpleValueUnion(ctxt, type, value);
+        if ((fireErrors) && (ret != 0)) {
+            xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_VALUE, "Failed to validate type %s\n", type->name, NULL);
+        }
     } else {
         TODO
     }