Integrated the streaming pattern from the pattern module. Fixed some IDC

* xmlschemas.c: Integrated the streaming pattern from the
  pattern module. Fixed some IDC code bugs. Changed
  fallback for attribute declaration addition to work like for
  element declarations.
diff --git a/xmlschemas.c b/xmlschemas.c
index d4d431d..8e291d0 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -34,7 +34,9 @@
 #include <libxml/xmlautomata.h>
 #include <libxml/xmlregexp.h>
 #include <libxml/dict.h>
-#include <libxml/xpath.h>
+#ifdef LIBXML_PATTERN_ENABLED
+#include <libxml/pattern.h>
+#endif
 
 /* #define DEBUG 1 */
 
@@ -258,7 +260,7 @@
     xmlSchemaIDCPtr idc;
     int index; /* an index position if significant for IDC key-sequences */
     const xmlChar *xpath; /* the XPath expression */
-    xmlXPathCompExprPtr xpathComp; /* the compiled XPath expression */
+    void *xpathComp; /* the compiled XPath expression */
 };
 
 /**
@@ -353,16 +355,16 @@
 typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
 typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
 struct _xmlSchemaIDCStateObj {
-    int type;
-    xmlSchemaIDCStateObjPtr parent; /* the parent selector state object */
+    int type;    
     xmlSchemaIDCStateObjPtr next; /* next if in a list */
-    int topDown;
-    int **history; /* list of (depth, state-id) tuples */
+    int depth; /* depth of creation */
+    int *history; /* list of (depth, state-id) tuples */
     int nbHistory;
     int sizeHistory;
     xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
                                        matcher */
     xmlSchemaIDCSelectPtr sel;
+    void *xpathCtxt;
 };
 
 #define IDC_MATCHER 0
@@ -2442,6 +2444,60 @@
     }    
 }
 
+#ifdef IDC_ENABLED
+static void
+xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
+{
+    xmlSchemaIDCStateObjPtr next;
+    while (sto != NULL) {
+	next = sto->next;
+	if (sto->history != NULL)
+	    xmlFree(sto->history);
+	if (sto->xpathCtxt != NULL)
+	    xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
+	xmlFree(sto);
+	sto = next;
+    }
+}
+
+/**
+ * xmlSchemaFreeIDC:
+ * @idc: a identity-constraint definition
+ *
+ * Deallocates an identity-constraint definition.
+ */
+static void
+xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
+{
+    xmlSchemaIDCSelectPtr cur, prev;
+
+    if (idcDef == NULL)
+	return;
+    if (idcDef->annot != NULL)
+        xmlSchemaFreeAnnot(idcDef->annot);
+    if (idcDef->ref != NULL)
+	xmlFree(idcDef->ref);
+    /* Selector */
+    if (idcDef->selector != NULL) {
+	if (idcDef->selector->xpathComp != NULL)
+	    xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
+	xmlFree(idcDef->selector);
+    }
+    /* Fields */
+    if (idcDef->fields != NULL) {
+	cur = idcDef->fields;
+	do {
+	    prev = cur;
+	    cur = cur->next;
+	    if (prev->xpathComp != NULL)
+		xmlFreePattern((xmlPatternPtr) prev->xpathComp);
+	    xmlFree(prev);	    
+	} while (cur != NULL);
+    }
+    xmlFree(idcDef);
+}
+#endif /* IDC_ENABLED */
+
 /**
  * xmlSchemaFreeElement:
  * @schema:  a schema element structure
@@ -2536,66 +2592,6 @@
     xmlFree(type);
 }
 
-#ifdef IDC_ENABLED
-static void
-xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
-{
-    xmlSchemaIDCStateObjPtr next;
-    while (sto != NULL) {
-	next = sto->next;
-	if (sto->history != NULL) {
-	    int i;
-	    for (i = 0; i < sto->sizeHistory; i++) {
-		if (sto->history[i] != NULL)
-		    xmlFree(sto->history[i]);
-		else 
-		    break;
-	    }
-	    xmlFree(sto->history);
-	}
-	xmlFree(sto);
-	sto = next;
-    }
-}
-
-/**
- * xmlSchemaFreeIDC:
- * @idc: a identity-constraint definition
- *
- * Deallocates an identity-constraint definition.
- */
-static void
-xmlSchemaFreeIDC(xmlSchemaIDCPtr idc)
-{
-    xmlSchemaIDCSelectPtr cur, prev;
-
-    if (idc == NULL)
-	return;
-    if (idc->annot != NULL)
-        xmlSchemaFreeAnnot(idc->annot);
-    if (idc->ref != NULL)
-	xmlFree(idc->ref);
-    /* Selector */
-    if (idc->selector != NULL) {
-	if (idc->selector->xpathComp != NULL)
-	    xmlXPathFreeCompExpr(idc->selector->xpathComp);
-	xmlFree(idc->selector);
-    }
-    /* Fields */
-    if (idc->fields != NULL) {
-	cur = idc->fields;
-	do {
-	    prev = cur;
-	    cur = cur->next;
-	    if (prev->xpathComp != NULL)
-		xmlXPathFreeCompExpr(prev->xpathComp);
-	    xmlFree(prev);	    
-	} while (cur != NULL);
-    }
-    xmlFree(idc);
-}
-#endif /* IDC_ENABLED */
-
 /**
  * xmlSchemaFreeTypeList:
  * @type:  a schema type structure
@@ -2644,6 +2640,11 @@
     if (schema->groupDecl != NULL)
         xmlHashFree(schema->groupDecl,
                     (xmlHashDeallocator) xmlSchemaFreeType);
+#ifdef IDC_ENABLED
+    if (schema->idcDef != NULL)
+        xmlHashFree(schema->idcDef,
+                    (xmlHashDeallocator) xmlSchemaFreeIDC);
+#endif
     if (schema->schemasImports != NULL)
 	xmlHashFree(schema->schemasImports,
 		    (xmlHashDeallocator) xmlSchemaFreeImport);
@@ -2964,14 +2965,12 @@
 		    value = xmlStrdup(BAD_CAST "dummy-value");
 		    res = 0;
 #endif
-		    if (res == 0)
+		    if (res >= 0)
 			fprintf(output, "\"%s\" ", value);
 		    else
 			fprintf(output, "CANON-VALUE-FAILED ");
-		    if (value != NULL) {
-			xmlFree(value);
-			value = NULL;
-		    }
+		    if (res == 0) 
+			FREE_AND_NULL(value)
 		} else if (key != NULL)
 		    fprintf(output, "(no val), ");
 		else
@@ -3553,8 +3552,7 @@
 	    xmlFree(ret);	    
 	    return (NULL);
 	} else {
-	    char buf[20];
-	    xmlChar *str;
+	    char buf[30];
 	    /*
 	    * Using the ctxt->container for xmlHashAddEntry3 is ambigious
 	    * in the scenario:
@@ -3564,24 +3562,21 @@
 	    * 2. those complex types contain attributes with an equal name
 	    * 3. those attributes are in no namespace 
 	    * We will compute a new context string.
-	    */
-	    snprintf(buf, 19, "%d", ctxt->counter++ + 1);
-	    str = xmlStrdup(BAD_CAST ctxt->container);
-	    str = xmlStrcat(str, BAD_CAST buf);
+	    */	    
+	    snprintf(buf, 29, "#aCont%d", ctxt->counter++ + 1);
 	    val = xmlHashAddEntry3(schema->attrDecl, name,
-		namespace, xmlDictLookup(ctxt->dict, str, -1), ret);
-	    FREE_AND_NULL(str)
+		namespace, BAD_CAST buf, ret);
+
 	    if (val != 0) {
 		xmlSchemaPCustomErr(ctxt,
 		    XML_SCHEMAP_INTERNAL,
 		    NULL, NULL, node,
-		    "Internal error: xmlSchemaAddElement, "
-		    "a dublicate element declaration with the name '%s' "
+		    "Internal error: xmlSchemaAddAttribute, "
+		    "a dublicate attribute declaration with the name '%s' "
 		    "could not be added to the hash.", name);
 		xmlFree(ret);
 		return (NULL);
-	    }
-	    
+	    }	    
 	}
     }
     if (ctxt->assemble != NULL)
@@ -3695,8 +3690,8 @@
 	    char buf[30]; 
 
 	    snprintf(buf, 29, "#eCont%d", ctxt->counter++ + 1);
-	    val = xmlHashAddEntry3(schema->elemDecl, name, (xmlChar *) buf,
-		namespace, ret);
+	    val = xmlHashAddEntry3(schema->elemDecl, name, 
+		namespace, (xmlChar *) buf, ret);
 	    if (val != 0) {
 		xmlSchemaPCustomErr(ctxt,
 		    XML_SCHEMAP_INTERNAL,
@@ -5844,19 +5839,19 @@
 	/*
 	* TODO: We need the array of in-scope namespaces for compilation.
 	*/	
-	selector->xpathComp = xmlXPathCompile(selector->xpath);
+	selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
+	    NULL, 0, NULL);
 #ifdef IDC_XPATH_SUPPORT
-	if ((selector->xpathComp == NULL) || 
-	    (xmlXPathWXSIDCValid(selector->xpathComp, isField) != 0)) {
+	if (selector->xpathComp == NULL) {
 	    xmlSchemaPCustomErr(ctxt,
-		/* TODO: Adjust error code? */
+		* TODO: Adjust error code? *
 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 
 		NULL, NULL, node, 
 		"The XPath expression '%s' could not be "
 		"compiled", selector->xpath);
 	    return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
 	}		
-#endif
+#endif  
     }
     return (0);
 }
@@ -6012,7 +6007,7 @@
     const xmlChar *name = NULL;
     xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
     int resAdd;
-    
+        
     /*
     * Check for illegal attributes.
     */
@@ -6077,7 +6072,6 @@
 	xmlFree(item);
 	return (NULL);
     }
-    
     memset(item, 0, sizeof(xmlSchemaIDC));
     item->name = name;
     item->type = idcCategory;  
@@ -13506,7 +13500,7 @@
 			* then a value needs not to checked against against a
 			* facet, thus no computed value is needed.
 			*/
-			if (item->baseType->flags && XML_SCHEMAS_TYPE_FACETSNEEDVALUE)
+			if (item->baseType->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE)
 			    item->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
 			else {
 			    for (cur = item->facetSet; cur != NULL;
@@ -16205,6 +16199,38 @@
 #ifdef IDC_ENABLED
 
 /**
+ * xmlSchemaAugmentIDC:
+ * @idcDef: the IDC definition
+ *
+ * Creates an augmented IDC definition item.
+ *
+ * Returns the item, or NULL on internal errors.
+ */
+static void
+xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef,
+		    xmlSchemaValidCtxtPtr vctxt)
+{
+    xmlSchemaIDCAugPtr aidc;
+
+    aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
+    if (aidc == NULL) {
+	xmlSchemaVErrMemory(vctxt, 
+	    "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
+	    NULL);
+	return;
+    }
+    aidc->bubbleDepth = -1;
+    aidc->def = idcDef;
+    aidc->next = NULL;
+    if (vctxt->aidcs == NULL)
+	vctxt->aidcs = aidc;
+    else {
+	aidc->next = vctxt->aidcs;
+	vctxt->aidcs = aidc;
+    }
+}
+
+/**
  * xmlSchemaIDCNewBinding:
  * @idcDef: the IDC definition of this binding
  *
@@ -16554,85 +16580,6 @@
 }
 
 /**
- * xmlSchemaXPathChangeState:
- * @vctxt: the WXS validation context
- * @sto: the state object
- * @newState: the state index to be added to the history
- *
- * Adds an entry (vctxt->depth and newState) to the history of the
- * state object.
- *
- * Returns 1 if they are equal, 0 if not and -1 on internal errors.
- */
-static int
-xmlSchemaXPathChangeState(xmlSchemaValidCtxtPtr vctxt,
-			xmlSchemaIDCStateObjPtr sto,
-			int newState)
-
-{
-    int *change = NULL;
-    /*
-    * Create/grow the array of history items.
-    */
-    if (sto->history == NULL) {
-	sto->history = (int **) xmlMalloc(5 * sizeof(int *));
-	if (sto->history == NULL) {
-	    xmlSchemaVErrMemory(NULL, 
-		"allocating an array of state change informations", NULL);
-	    xmlFree(sto);
-	    return(-1);
-	}
-	memset(sto->history, 0, 5 * sizeof(int *));
-	sto->sizeHistory = 10;
-    } else if (sto->sizeHistory > sto->nbHistory) {
-	/*
-	* Reuse a history item.
-	*/
-	change = sto->history[sto->nbHistory];
-    } else {
-	int i = sto->sizeHistory;
-
-	sto->sizeHistory *= 2;
-	sto->history = (int **) xmlRealloc(sto->history, 
-	    sto->sizeHistory * sizeof(int *));
-	if (sto->history == NULL) {
-	    xmlSchemaVErrMemory(NULL, 
-		"re-allocating an array of state change informations", NULL);
-	    return(-1);
-	}
-	/*
-	* The new memory needs to be NULLed.
-	* TODO: Use memset instead?
-	*/
-	for (; i < sto->sizeHistory; i++)
-	    sto->history[i] = NULL;    
-    }	
-    /*
-    * Create the history item.
-    */
-    if (change == NULL) {
-	change = (int *) xmlMalloc(2 * sizeof(int));
-	if (change == NULL) {
-	    xmlSchemaVErrMemory(NULL, 
-		"allocating a state change information", NULL);
-	    return(-1);
-	}
-	sto->history[sto->nbHistory] = change;
-    }
-    sto->nbHistory++;
-    /*
-    * Init the history item.
-    */
-    change[0] = vctxt->depth;
-    change[1] = newState;
-#ifdef DEBUG_IDC
-    xmlGenericError(xmlGenericErrorContext, "IDC:       push state '%d'\n",
-	newState);
-#endif
-    return(0);
-}
-
-/**
  * xmlSchemaIDCAddStateObject:
  * @vctxt: the WXS validation context
  * @matcher: the IDC matcher
@@ -16650,68 +16597,65 @@
 xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
 			xmlSchemaIDCMatcherPtr matcher,
 			xmlSchemaIDCSelectPtr sel,
-			xmlSchemaIDCStateObjPtr parent,
 			int type)
 {
     xmlSchemaIDCStateObjPtr sto;
-    int i = 0, stateId, reversed;
 
     /*
-    * Create a state object for every location path in the XPath expression.
+    * Reuse the state objects from the pool.
     */
-    while (1) {
-#ifdef IDC_XPATH_SUPPORT
-	stateId = xmlXPathWXSIDCGetLocationPath(sel->xpathComp, i, &reversed);
-#else
-	break;
-#endif
-	if (stateId < 0)
-	    break;
+    if (vctxt->xpathStatePool != NULL) {
+	sto = vctxt->xpathStatePool;
+	vctxt->xpathStatePool = sto->next;
+	sto->next = NULL;
+    } else {	
 	/*
-	* Reuse the state objects from the pool.
+	* Create a new state object.
 	*/
-	if (vctxt->xpathStatePool != NULL) {
-	    sto = vctxt->xpathStatePool;
-	    vctxt->xpathStatePool = sto->next;
-	    sto->next = NULL;
-	} else {	
-	    /*
-	    * Create a new state object.
-	    */
-	    sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
-	    if (sto == NULL) {
-		xmlSchemaVErrMemory(NULL,
-		    "allocating an IDC state object", NULL);
-		return (-1);
-	    }
-	    memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
-	}	
-	sto->type = type;
-	sto->parent = parent;
-	sto->matcher = matcher;
-	sto->sel = sel;
-	sto->nbHistory = 0;	
-	/*
-	* Add to global list. 
-	*/	
-	if (vctxt->xpathStates != NULL)
-	    sto->next = vctxt->xpathStates;
-	vctxt->xpathStates = sto;
-#if DEBUG_IDC
-	xmlGenericError(xmlGenericErrorContext, "IDC:   STO push '%s'\n",
-	    sto->sel->xpath);
-#endif		
-	xmlSchemaXPathChangeState(vctxt, sto, stateId);
-	/*
-	* Set if the state object should be processed as a push
-	* down transducer (topDown == 1) or upwards the ancestor axis of
-	* the tree.
-	*/
-	if (reversed)
-	    sto->topDown = 1;	
-	i++;
-    };
+	sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
+	if (sto == NULL) {
+	    xmlSchemaVErrMemory(NULL,
+		"allocating an IDC state object", NULL);
+	    return (-1);
+	}
+	memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
+    }	
+    /*
+    * Add to global list. 
+    */	
+    if (vctxt->xpathStates != NULL)
+	sto->next = vctxt->xpathStates;
+    vctxt->xpathStates = sto;
 
+    /*
+    * Free the old xpath validation context.
+    */
+    if (sto->xpathCtxt != NULL)
+	xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
+
+    /*
+    * Create a new XPath (pattern) validation context.
+    */
+    sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
+	(xmlPatternPtr) sel->xpathComp);
+    if (sto->xpathCtxt == NULL) {
+	xmlSchemaVErr(vctxt, vctxt->node,
+	    XML_SCHEMAV_INTERNAL,
+	    "Internal error: xmlSchemaIDCAddStateObject, "
+	    "failed to create the XPath validation context.\n",
+	    NULL, NULL);
+	return (-1);
+    }    
+    sto->type = type;
+    sto->depth = vctxt->depth;
+    sto->matcher = matcher;
+    sto->sel = sel;
+    sto->nbHistory = 0;
+    
+#if DEBUG_IDC
+    xmlGenericError(xmlGenericErrorContext, "IDC:   STO push '%s'\n",
+	sto->sel->xpath);
+#endif
     return (0);
 }
 
@@ -16732,7 +16676,6 @@
 		       xmlElementType nodeType)
 {
     xmlSchemaIDCStateObjPtr sto, head = NULL, first;
-    int retState, *change;
     int res, resolved = 0;
         
     if (vctxt->xpathStates == NULL)
@@ -16753,142 +16696,66 @@
     first = vctxt->xpathStates;
     sto = first;
     while (sto != head) {
-	/*
-	* Evaluate:
-	* 1. all bottom-up state objs.
-	* 2. top-down state objs. which are not marked as
-	*    matching or blocking.
-	* Note: sto->history[0][0] will hold the depth of creation.
-	*/
-	if (sto->topDown == 0) {
-	    /*
-	    * Always start from the beginning with bottom-up
-	    * evaluation.
-	    */
-	    change = sto->history[0];
-	} else {
-	    change = sto->history[sto->nbHistory -1];
-	    if (change[1] < 0)
-		goto next_sto;
-	}
-	/*
-	* change[0] holds the depth of change.
-	* change[1] holds the state index or the "match" or "blocked"
-	* indicator.
-	*/
-	retState = -1;
 #if DEBUG_IDC
-	if (sto->type == XPATH_STATE_OBJ_IDC_SELECTOR)
+	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
 	    xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] selector '%s'\n", 
 		sto->matcher->aidc->def->name, sto->sel->xpath);
 	else
 	    xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] field '%s'\n", 
 		sto->matcher->aidc->def->name, sto->sel->xpath);
 #endif
-	if (sto->topDown == 0) {
-	    /*
-	    * The XPath will be evaluated using the
-	    * ancestor-or-self axis.
-	    */
-#ifdef IDC_XPATH_SUPPORT
-	    res = xmlXPathWXSIDCEvalOneNode(sto->sel->xpathComp, 
-		change[1], &retState, nodeType,
-		localName, namespaceName);
-#else
-	    res = 0;
-#endif
-	    if (res == 1) {
-		int i;
 
-		if (nodeType == XML_ELEMENT_NODE)
-		    i = vctxt->depth -1;
-		else
-		    i = vctxt->depth;
-		while ((res == 1) && (i >= 0)) {
-		    /*
-		    * If we get a partial match, evaluate the
-		    * ancestor axis.
-		    */
 #ifdef IDC_XPATH_SUPPORT
-		    res = xmlXPathWXSIDCEvalOneNode(sto->sel->xpathComp, 
-			retState, &retState, XML_ELEMENT_NODE,
-			vctxt->elemInfos[i]->localName, 
-			vctxt->elemInfos[i]->namespaceName);
-#endif
-		    i--;
-		}
-	    }
-	    if (res == -1) {
-		xmlSchemaVErr(vctxt, vctxt->node,
-		    XML_SCHEMAV_INTERNAL,
-		    "Internal error: xmlSchemaXPathEvaluate, "
-		    "failed to evaluate a node.\n",
-		    NULL, NULL);
-		return (-1);
-	    } else if (res != 2) {
-		/*
-		* We will record matches only.
-		*/
-#if DEBUG_IDC
-		xmlGenericError(xmlGenericErrorContext, "IDC:     "
-		    "no match\n");
-#endif
-		goto next_sto;
-	    }
-	} else {
-	    /*
-	    * Push-down.
-	    */
-#ifdef IDC_XPATH_SUPPORT
-	    res = xmlXPathWXSIDCEvalOneNode(sto->sel->xpathComp, 
-		change[1], &retState, nodeType,
-		localName, namespaceName);
+	res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
+	    localName, namespaceName);	    
 #else
-	    res = 0;
+	res = 0;
 #endif
-	    if (res == -1) {
-		xmlSchemaVErr(vctxt, vctxt->node,
-		    XML_SCHEMAV_INTERNAL,
-		    "Internal error: xmlSchemaXPathEvaluate, "
-		    "failed to evaluate a node.\n",
-		    NULL, NULL);
-		return (-1);
-	    } else if (res == 0) {
-		/*
-		* No Match.
-		*/
-#if DEBUG_IDC
-		xmlGenericError(xmlGenericErrorContext,
-		    "IDC:     no match, blocked\n");
-#endif
-		if (xmlSchemaXPathChangeState(vctxt, sto, -3) == -1)
-		    return (-1);
-	    } else if (res == 1) {
-		/*
-		* Partial match.
-		*/
-#if DEBUG_IDC
-		xmlGenericError(xmlGenericErrorContext,
-		    "IDC:     partial match\n");
-#endif
-		if (xmlSchemaXPathChangeState(vctxt, sto, retState) == -1)
-		    return (-1);
-	    }
+	if (res == -1) {
+	    xmlSchemaVErr(vctxt, vctxt->node,
+		XML_SCHEMAV_INTERNAL,
+		"Internal error: xmlSchemaXPathEvaluate, "
+		"failed to evaluate a node.\n",
+		NULL, NULL);
+	    return (-1);
 	}
-	if (res != 2)
+	if (res == 0)
 	    goto next_sto;
 	/*
 	* Full match.
 	*/
 #if DEBUG_IDC
 	xmlGenericError(xmlGenericErrorContext, "IDC:     "
-	    "final match\n");
+	    "MATCH\n");
 #endif
 	/*
-	* Register a state-change.
-	*/			
-	if (xmlSchemaXPathChangeState(vctxt, sto, -2) == -1)
-	    return (-1);
+	* Register a match in the state object history.
+	*/
+	if (sto->history == NULL) {
+	    sto->history = (int *) xmlMalloc(5 * sizeof(int));
+	    if (sto->history == NULL) {
+		xmlSchemaVErrMemory(NULL, 
+		    "allocating the state object history", NULL);
+		return(-1);
+	    }
+	    sto->sizeHistory = 10;
+	} else if (sto->sizeHistory <= sto->nbHistory) {
+	    sto->sizeHistory *= 2;
+	    sto->history = (int *) xmlRealloc(sto->history,
+		sto->sizeHistory * sizeof(int));
+	    if (sto->history == NULL) {
+		xmlSchemaVErrMemory(NULL, 
+		    "re-allocating the state object history", NULL);
+		return(-1);
+	    }
+	}		
+	sto->history[sto->nbHistory++] = vctxt->depth;
+
+#ifdef DEBUG_IDC
+	xmlGenericError(xmlGenericErrorContext, "IDC:       push match '%d'\n",
+	    vctxt->depth);
+#endif
+
 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
 	    xmlSchemaIDCSelectPtr sel;
 	    /*
@@ -16901,9 +16768,9 @@
 #endif
 	    sel = sto->matcher->aidc->def->fields;
 	    while (sel != NULL) {
-		if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher, 
-		    sel, sto, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
-		    return (-1);				
+		if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
+		    sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
+		    return (-1);
 		sel = sel->next;
 	    }
 	} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
@@ -16925,7 +16792,7 @@
 next_sto:
 	if (sto->next == NULL) {
 	    /*
-	    * Evaluate field state objects created on this node.
+	    * Evaluate field state objects created on this node as well.
 	    */
 	    head = first;
 	    sto = vctxt->xpathStates;
@@ -16950,7 +16817,7 @@
 			     xmlSchemaTypePtr type)
 {
     xmlSchemaIDCStateObjPtr sto, nextsto;
-    int res, *change;
+    int res, matchDepth;
     xmlSchemaPSVIIDCKeyPtr key = NULL;
 
     if (vctxt->xpathStates == NULL)
@@ -16972,381 +16839,364 @@
     * Evaluate the state objects.
     */
     while (sto != NULL) {
-	/*
-	* If (nbHistory == 1) then there are no history left
-	* (only the initial one), so deregister the state object.
-	*/
-    	if (sto->nbHistory == 1)
+	if (sto->nbHistory == 0)
 	    goto deregister_check;
 
-	change = sto->history[sto->nbHistory -1];
+	matchDepth = sto->history[sto->nbHistory -1];
 
 	/*
-	* Ony history at the current depth are of interest.
+	* Only matches at the current depth are of interest.
 	*/
-	if (change[0] != vctxt->depth) {
+	if (matchDepth != vctxt->depth) {
 	    sto = sto->next;
 	    continue;
 	}
-
-	if (change[1] == -2) {
-	    if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
-		if (! IS_SIMPLE_TYPE(type)) {
-		    /*
-		    * Not qualified if the field resolves to a node of non
-		    * simple type.
-		    */	
-		    xmlSchemaVCustomErr(vctxt,
-			XML_SCHEMAV_CVC_IDC,
-			vctxt->node, 
-			(xmlSchemaTypePtr) sto->matcher->aidc->def,
-			"The field '%s' does evaluate to a node of "
-			"non-simple type", sto->sel->xpath);
-
-		    sto->nbHistory--;
-		    sto = sto->next;
-		    continue;
-		}
-		if (vctxt->value == NULL) {
-		    /*
-		    * Failed to provide the normalized value; maby
-		    * the value was invalid.
-		    */ 
-		    xmlSchemaVErr(vctxt, NULL, 
-			XML_SCHEMAV_INTERNAL,
-			"Internal error: xmlSchemaIDCEvaluateMatches, "
-			"normalized node value not available.\n", 
-			NULL, NULL);
-		    sto->nbHistory--;
-		    sto = sto->next;
-		    continue;
-		} else {
-		    xmlSchemaIDCMatcherPtr matcher = sto->matcher;
-		    xmlSchemaPSVIIDCKeyPtr *keySeq;
-		    int pos, sizeNeeded, index;
-
-		    /*
-		    * The key will be anchored on the matcher's list of
-		    * key-sequences. The position in this list is determined
-		    * by the target node's depth relative to the matcher's
-		    * depth of creation (i.e. the depth of the scope element).
-		    * Note that sto->parent will be the selector state object,
-		    * which resolved to a target node. Since this match was
-		    * recorded in the last change entry, we can obtain the
-		    * depth of the target node from there.
-		    */		    
-		    pos = sto->parent->history[sto->parent->nbHistory -1][0] -
-			matcher->depth;
-		    sizeNeeded = pos;
-		    index = sto->sel->index;
-
-		    /*
-		    * Create/grow the array of key-sequences.
-		    */
+	
+	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
+	    if (! IS_SIMPLE_TYPE(type)) {
+		/*
+		* Not qualified if the field resolves to a node of non
+		* simple type.
+		*/	
+		xmlSchemaVCustomErr(vctxt,
+		    XML_SCHEMAV_CVC_IDC,
+		    vctxt->node, 
+		    (xmlSchemaTypePtr) sto->matcher->aidc->def,
+		    "The field '%s' does evaluate to a node of "
+		    "non-simple type", sto->sel->xpath);
+		
+		sto->nbHistory--;
+		goto deregister_check;
+	    }
+	    if ((key == NULL) && (vctxt->value == NULL)) {
+		/*
+		* Failed to provide the normalized value; maby
+		* the value was invalid.
+		*/ 
+		xmlSchemaVErr(vctxt, NULL, 
+		    XML_SCHEMAV_INTERNAL,
+		    "Internal error: xmlSchemaIDCEvaluateMatches, "
+		    "normalized node value not available.\n", 
+		    NULL, NULL);
+		sto->nbHistory--;
+		goto deregister_check;
+	    } else {
+		xmlSchemaIDCMatcherPtr matcher = sto->matcher;
+		xmlSchemaPSVIIDCKeyPtr *keySeq;
+		int pos, index;
+		
+		/*
+		* The key will be anchored on the matcher's list of
+		* key-sequences. The position in this list is determined
+		* by the target node's depth relative to the matcher's
+		* depth of creation (i.e. the depth of the scope element).
+		*/		    
+		pos = sto->depth - matcher->depth;
+		index = sto->sel->index;
+		
+		/*
+		* Create/grow the array of key-sequences.
+		*/
+		if (matcher->keySeqs == NULL) {
+		    if (pos > 9) 
+			matcher->sizeKeySeqs = pos * 2;
+		    else
+			matcher->sizeKeySeqs = 10;
+		    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **) 
+			xmlMalloc(matcher->sizeKeySeqs *
+			sizeof(xmlSchemaPSVIIDCKeyPtr *));			
+		    if (matcher->keySeqs == NULL) {		
+			xmlSchemaVErrMemory(NULL,
+			    "allocating an array of key-sequences",
+			    NULL);
+			return(-1);
+		    }
+		    memset(matcher->keySeqs, 0,
+			matcher->sizeKeySeqs *
+			sizeof(xmlSchemaPSVIIDCKeyPtr *));
+		} else if (pos >= matcher->sizeKeySeqs) {	
+		    int i = matcher->sizeKeySeqs;
+		    
+		    matcher->sizeKeySeqs *= 2;
+		    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
+			xmlRealloc(matcher->keySeqs,
+			matcher->sizeKeySeqs *
+			sizeof(xmlSchemaPSVIIDCKeyPtr *));
 		    if (matcher->keySeqs == NULL) {
-			if (pos > 9) 
-			    matcher->sizeKeySeqs = pos * 2;
-			else
-			    matcher->sizeKeySeqs = 10;
-			matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **) 
-			    xmlMalloc(matcher->sizeKeySeqs *
-			    sizeof(xmlSchemaPSVIIDCKeyPtr *));			
-			if (matcher->keySeqs == NULL) {		
-			    xmlSchemaVErrMemory(NULL,
-				"allocating an array of key-sequences",
-				NULL);
-			    return(-1);
-			}
-			memset(matcher->keySeqs, 0,
-			    matcher->sizeKeySeqs *
-			    sizeof(xmlSchemaPSVIIDCKeyPtr *));
-		    } else if (pos >= matcher->sizeKeySeqs) {	
-			int i = matcher->sizeKeySeqs;
-
-			matcher->sizeKeySeqs *= 2;
-			matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
-			    xmlRealloc(matcher->keySeqs,
-			    matcher->sizeKeySeqs *
-			    sizeof(xmlSchemaPSVIIDCKeyPtr *));
-			if (matcher->keySeqs == NULL) {
-			    xmlSchemaVErrMemory(NULL,
-				"reallocating an array of key-sequences",
-				NULL);
-			    return (-1);
-			}
-			/*
-			* The array needs to be NULLed.
-			* TODO: Use memset?
-			*/
-			for (; i < matcher->sizeKeySeqs; i++) 
-			    matcher->keySeqs[i] = NULL;			
+			xmlSchemaVErrMemory(NULL,
+			    "reallocating an array of key-sequences",
+			    NULL);
+			return (-1);
 		    }
-		    
 		    /*
-		    * Get/create the key-sequence.
+		    * The array needs to be NULLed.
+		    * TODO: Use memset?
 		    */
-		    keySeq = matcher->keySeqs[pos];		    
-		    if (keySeq == NULL) {	
-			goto create_sequence;
-		    } else {
-			if (keySeq[index] != NULL) {
-			    /*
-			    * cvc-identity-constraint:
-			    * 3 For each node in the ·target node set· all
-			    * of the {fields}, with that node as the context
-			    * node, evaluate to either an empty node-set or
-			    * a node-set with exactly one member, which must
-			    * have a simple type.
-			    * 
-			    * The key was already set; report an error.
-			    */
-			    xmlSchemaVCustomErr(vctxt, 
-				XML_SCHEMAV_CVC_IDC,
-				vctxt->node, (xmlSchemaTypePtr) matcher->aidc->def,
-				"The field '%s' evaluates to a node-set "
-				"with more than one member", sto->sel->xpath);
-			    return (1);
-			} else {
-			    goto create_key;
-			}
-		    }
-
-create_sequence:
-		    /*
-		    * Create a key-sequence.
-		    */
-		    keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
-			matcher->aidc->def->nbFields * 
-			sizeof(xmlSchemaPSVIIDCKeyPtr));
-		    if (keySeq == NULL) {
-			xmlSchemaVErrMemory(NULL, 
-			    "allocating an IDC key-sequence", NULL);
-			return(-1);			
-		    }	
-		    memset(keySeq, 0, matcher->aidc->def->nbFields * 
-			sizeof(xmlSchemaPSVIIDCKeyPtr));
-		    matcher->keySeqs[pos] = keySeq;
-create_key:
-		    /*
-		    * Created a key once per node only.
-		    */  
-		    if (key == NULL) {
-			key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
-			    sizeof(xmlSchemaPSVIIDCKey));
-			if (key == NULL) {
-			    xmlSchemaVErrMemory(NULL,
-				"allocating a IDC key", NULL);
-			    xmlFree(keySeq);
-			    matcher->keySeqs[pos] = NULL;
-			    return(-1);			
-			}
-			/*
-			* Consume the compiled value.
-			*/
-			key->type = type;
-			key->compValue = vctxt->value;
-			vctxt->value = NULL;
-			/*
-			* Store the key in a global list.
-			*/
-			if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
-			    xmlSchemaIDCFreeKey(key);
-			    return (-1);
-			}
-		    }
-		    keySeq[index] = key;		    
-		}
-	    } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
-		
-		xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
-		xmlSchemaPSVIIDCBindingPtr bind;
-		xmlSchemaPSVIIDCNodePtr ntItem;
-		xmlSchemaIDCMatcherPtr matcher;
-		xmlSchemaIDCPtr idc;
-		int pos, i, j, nbKeys;
-		/*
-		* Here we have the following scenario:
-		* An IDC 'selector' state object resolved to a target node,
-		* during the time this target node was in the 
-		* ancestor-or-self axis, the 'field' state object(s) looked 
-		* out for matching nodes to create a key-sequence for this 
-		* target node. Now we are back to this target node and need
-		* to put the key-sequence, together with the target node 
-		* itself, into the node-table of the corresponding IDC 
-		* binding.
-		*/
-		matcher = sto->matcher;
-		idc = matcher->aidc->def;
-		nbKeys = idc->nbFields;
-		pos = vctxt->depth - matcher->depth;		
-		/*
-		* Check if the matcher has any key-sequences at all, plus
-		* if it has a key-sequence for the current target node.
-		*/		
-		if ((matcher->keySeqs == NULL) ||
-		    (matcher->sizeKeySeqs <= pos)) {
-		    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
-			goto selector_key_error;
-		    else
-			goto selector_leave;
+		    for (; i < matcher->sizeKeySeqs; i++) 
+			matcher->keySeqs[i] = NULL;			
 		}
 		
-		keySeq = &(matcher->keySeqs[pos]);		
-		if (*keySeq == NULL) {
-		    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
-			goto selector_key_error;
-		    else
-			goto selector_leave;
-		}
-		
-		for (i = 0; i < nbKeys; i++) {
-		    if (*keySeq[i] == NULL) {
+		/*
+		* Get/create the key-sequence.
+		*/
+		keySeq = matcher->keySeqs[pos];		    
+		if (keySeq == NULL) {	
+		    goto create_sequence;
+		} else {
+		    if (keySeq[index] != NULL) {
 			/*
-			* Not qualified, if not all fields did resolve.
-			*/
-			if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
-			    /*
-			    * All fields of a "key" IDC must resolve.
-			    */
-			    goto selector_key_error;
-			}		    
-			goto selector_leave;
-		    }
-		}
-		/*
-		* All fields did resolve.
-		*/
-
-		/*
-		* 4.1 If the {identity-constraint category} is unique(/key),
-		* then no two members of the ·qualified node set· have
-		* ·key-sequences· whose members are pairwise equal, as
-		* defined by Equal in [XML Schemas: Datatypes].
-		*
-		* Get the IDC binding from the matcher and check for
-		* duplicate key-sequences.
-		*/
-		bind = xmlSchemaIDCAquireBinding(vctxt, matcher);
-		if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) && 
-		    (bind->nbNodes != 0)) {
-		    xmlSchemaPSVIIDCKeyPtr key, bkey, *bkeySeq;
-		    
-		    i = 0;
-		    /*
-		    * Compare the key-sequences, key by key.
-		    */
-		    do {
-			bkeySeq = bind->nodeTable[i]->keys;
-			for (j = 0; j < nbKeys; j++) {
-			    key = *keySeq[j];
-			    bkey = bkeySeq[j];							
-			    res = xmlSchemaAreValuesEqual(key->type,
-				key->compValue, bkey->type, bkey->compValue);
-			    if (res == -1) {
-				return (-1);
-			    } else if (res == 0)
-				break;
-			}
-			if (res == 1) {
-			    /*
-			    * Duplicate found.
-			    */
-			    break;
-			}
-			i++;
-		    } while (i < bind->nbNodes);
-		    if (i != bind->nbNodes) {
-			/*   
-			* TODO: Try to report the key-sequence.
+			* cvc-identity-constraint:
+			* 3 For each node in the ·target node set· all
+			* of the {fields}, with that node as the context
+			* node, evaluate to either an empty node-set or
+			* a node-set with exactly one member, which must
+			* have a simple type.
+			* 
+			* The key was already set; report an error.
 			*/
 			xmlSchemaVCustomErr(vctxt, 
 			    XML_SCHEMAV_CVC_IDC,
-			    vctxt->node,
-			    (xmlSchemaTypePtr) idc,
-			    "Duplicate key-sequence found", NULL);
-			
-			goto selector_leave;
+			    vctxt->node, (xmlSchemaTypePtr) matcher->aidc->def,
+			    "The field '%s' evaluates to a node-set "
+			    "with more than one member", sto->sel->xpath);
+			sto->nbHistory--;
+			goto deregister_check;
+		    } else {
+			goto create_key;
 		    }
 		}
-		/*
-		* Add a node-table item to the IDC binding.
-		*/
-		ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
-		    sizeof(xmlSchemaPSVIIDCNode));
-		if (ntItem == NULL) {
-		    xmlSchemaVErrMemory(NULL, 
-			"allocating an IDC node-table item", NULL);
-		    xmlFree(*keySeq);
-		    *keySeq = NULL;
-		    return(-1);
-		}	
-		memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));		
 		
-		/* 
-		* Store the node-table item on global list.
+create_sequence:
+		/*
+		* Create a key-sequence.
 		*/
-		if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
-		    if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
-			xmlFree(ntItem);
-			xmlFree(*keySeq);
-			*keySeq = NULL;
+		keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
+		    matcher->aidc->def->nbFields * 
+		    sizeof(xmlSchemaPSVIIDCKeyPtr));
+		if (keySeq == NULL) {
+		    xmlSchemaVErrMemory(NULL, 
+			"allocating an IDC key-sequence", NULL);
+		    return(-1);			
+		}	
+		memset(keySeq, 0, matcher->aidc->def->nbFields * 
+		    sizeof(xmlSchemaPSVIIDCKeyPtr));
+		matcher->keySeqs[pos] = keySeq;
+create_key:
+		/*
+		* Created a key once per node only.
+		*/  
+		if (key == NULL) {
+		    key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
+			sizeof(xmlSchemaPSVIIDCKey));
+		    if (key == NULL) {
+			xmlSchemaVErrMemory(NULL,
+			    "allocating a IDC key", NULL);
+			xmlFree(keySeq);
+			matcher->keySeqs[pos] = NULL;
+			return(-1);			
+		    }
+		    /*
+		    * Consume the compiled value.
+		    */
+		    key->type = type;
+		    key->compValue = vctxt->value;
+		    vctxt->value = NULL;
+		    /*
+		    * Store the key in a global list.
+		    */
+		    if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
+			xmlSchemaIDCFreeKey(key);
 			return (-1);
 		    }
 		}
-		/*
-		* Init the node-table item. Consume the key-sequence.
-		*/
-		ntItem->node = vctxt->node;
-		ntItem->keys = *keySeq;
-		*keySeq = NULL;
-		if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1) {		    
-		    if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
-			/* 
-			* Free the item, since keyref items won't be
-			* put on a global list.
-			*/
-			xmlFree(ntItem->keys);
-			xmlFree(ntItem);
-		    }
-		    return (-1);
-		}
+		keySeq[index] = key;		    
+	    }
+	} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
 		
-		goto selector_leave;
-selector_key_error:
+	    xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
+	    xmlSchemaPSVIIDCBindingPtr bind;
+	    xmlSchemaPSVIIDCNodePtr ntItem;
+	    xmlSchemaIDCMatcherPtr matcher;
+	    xmlSchemaIDCPtr idc;
+	    int pos, i, j, nbKeys;
+	    /*
+	    * Here we have the following scenario:
+	    * An IDC 'selector' state object resolved to a target node,
+	    * during the time this target node was in the 
+	    * ancestor-or-self axis, the 'field' state object(s) looked 
+	    * out for matching nodes to create a key-sequence for this 
+	    * target node. Now we are back to this target node and need
+	    * to put the key-sequence, together with the target node 
+	    * itself, into the node-table of the corresponding IDC 
+	    * binding.
+	    */
+	    matcher = sto->matcher;
+	    idc = matcher->aidc->def;
+	    nbKeys = idc->nbFields;
+	    pos = vctxt->depth - matcher->depth;		
+	    /*
+	    * Check if the matcher has any key-sequences at all, plus
+	    * if it has a key-sequence for the current target node.
+	    */		
+	    if ((matcher->keySeqs == NULL) ||
+		(matcher->sizeKeySeqs <= pos)) {
+		if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
+		    goto selector_key_error;
+		else
+		    goto selector_leave;
+	    }
+	    
+	    keySeq = &(matcher->keySeqs[pos]);		
+	    if (*keySeq == NULL) {
+		if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
+		    goto selector_key_error;
+		else
+		    goto selector_leave;
+	    }
+	    
+	    for (i = 0; i < nbKeys; i++) {
+		if ((*keySeq)[i] == NULL) {
+		    /*
+		    * Not qualified, if not all fields did resolve.
+		    */
+		    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
+			/*
+			* All fields of a "key" IDC must resolve.
+			*/
+			goto selector_key_error;
+		    }		    
+		    goto selector_leave;
+		}
+	    }
+	    /*
+	    * All fields did resolve.
+	    */
+	    
+	    /*
+	    * 4.1 If the {identity-constraint category} is unique(/key),
+	    * then no two members of the ·qualified node set· have
+	    * ·key-sequences· whose members are pairwise equal, as
+	    * defined by Equal in [XML Schemas: Datatypes].
+	    *
+	    * Get the IDC binding from the matcher and check for
+	    * duplicate key-sequences.
+	    */
+	    bind = xmlSchemaIDCAquireBinding(vctxt, matcher);
+	    if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) && 
+		(bind->nbNodes != 0)) {
+		xmlSchemaPSVIIDCKeyPtr key, bkey, *bkeySeq;
+		
+		i = 0;
 		/*
-		* 4.2.1 (KEY) The ·target node set· and the 
-		* ·qualified node set· are equal, that is, every 
-		* member of the ·target node set· is also a member
-		* of the ·qualified node set· and vice versa.
+		* Compare the key-sequences, key by key.
 		*/
-		xmlSchemaVCustomErr(vctxt, 
-		    XML_SCHEMAV_CVC_IDC,
-		    vctxt->node, 
-		    (xmlSchemaTypePtr) idc,
-		    "All 'key' fields must evaluate to a node",
-		    NULL);
-selector_leave:
-		/*
-		* Free the key-sequence if not added to the IDC table.
-		*/
-		if (*keySeq != NULL) {
+		do {
+		    bkeySeq = bind->nodeTable[i]->keys;
+		    for (j = 0; j < nbKeys; j++) {
+			key = (*keySeq)[j];
+			bkey = bkeySeq[j];							
+			res = xmlSchemaAreValuesEqual(key->type,
+			    key->compValue, bkey->type, bkey->compValue);
+			if (res == -1) {
+			    return (-1);
+			} else if (res == 0)
+			    break;
+		    }
+		    if (res == 1) {
+			/*
+			* Duplicate found.
+			*/
+			break;
+		    }
+		    i++;
+		} while (i < bind->nbNodes);
+		if (i != bind->nbNodes) {
+		    /*   
+		    * TODO: Try to report the key-sequence.
+		    */
+		    xmlSchemaVCustomErr(vctxt, 
+			XML_SCHEMAV_CVC_IDC,
+			vctxt->node,
+			(xmlSchemaTypePtr) idc,
+			"Duplicate key-sequence found", NULL);
+		    
+		    goto selector_leave;
+		}
+	    }
+	    /*
+	    * Add a node-table item to the IDC binding.
+	    */
+	    ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
+		sizeof(xmlSchemaPSVIIDCNode));
+	    if (ntItem == NULL) {
+		xmlSchemaVErrMemory(NULL, 
+		    "allocating an IDC node-table item", NULL);
+		xmlFree(*keySeq);
+		*keySeq = NULL;
+		return(-1);
+	    }	
+	    memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));		
+	    
+	    /* 
+	    * Store the node-table item on global list.
+	    */
+	    if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
+		if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
+		    xmlFree(ntItem);
 		    xmlFree(*keySeq);
 		    *keySeq = NULL;
+		    return (-1);
 		}
-	    } /* if selector */
-	} /* if matched */
-
+	    }
+	    /*
+	    * Init the node-table item. Consume the key-sequence.
+	    */
+	    ntItem->node = vctxt->node;
+	    ntItem->keys = *keySeq;
+	    *keySeq = NULL;
+	    if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1) {		    
+		if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
+		    /* 
+		    * Free the item, since keyref items won't be
+		    * put on a global list.
+		    */
+		    xmlFree(ntItem->keys);
+		    xmlFree(ntItem);
+		}
+		return (-1);
+	    }
+	    
+	    goto selector_leave;
+selector_key_error:
+	    /*
+	    * 4.2.1 (KEY) The ·target node set· and the 
+	    * ·qualified node set· are equal, that is, every 
+	    * member of the ·target node set· is also a member
+	    * of the ·qualified node set· and vice versa.
+	    */
+	    xmlSchemaVCustomErr(vctxt, 
+		XML_SCHEMAV_CVC_IDC,
+		vctxt->node, 
+		(xmlSchemaTypePtr) idc,
+		"All 'key' fields must evaluate to a node",
+		NULL);
+selector_leave:
+	    /*
+	    * Free the key-sequence if not added to the IDC table.
+	    */
+	    if (*keySeq != NULL) {
+		xmlFree(*keySeq);
+		*keySeq = NULL;
+	    }
+	} /* if selector */
+	
 	sto->nbHistory--;
 
 deregister_check:
 	/*
 	* Deregister state objects if they reach the depth of creation.
-	* Note that this has to be checked before and after processing
-	* any history if the state object resolved to partially/fully
-	* to a node on which it was created as well, since this scenario
-	* created two entries in the list of history for the same node.
 	*/
-	if ((sto->nbHistory == 1) && (sto->history[0][0] == vctxt->depth)) {
+	if ((sto->nbHistory == 0) && (sto->depth == vctxt->depth)) {
 #if DEBUG_IDC
 	    xmlGenericError(xmlGenericErrorContext, "IDC:   STO pop '%s'\n",
 		sto->sel->xpath);
@@ -17359,7 +17209,6 @@
 		    "in the list.\n",
 		    NULL, NULL);
 	    }
-	    sto->nbHistory = 0;
 	    nextsto = sto->next;
 	    /*
 	    * Unlink from the list of active XPath state objects.
@@ -17398,13 +17247,13 @@
     idc = (xmlSchemaIDCPtr) elemDecl->idcs;
     if (idc == NULL)
 	return (0);
-    
+
 #if DEBUG_IDC
     {
 	xmlChar *str = NULL;
 	xmlGenericError(xmlGenericErrorContext, 
-	    "IDC: MATCHERS on %s, depth %d\n",
-	    xmlSchemaFormatNsUriLocal(&str, vctxt->elemInfo->namespaceName,
+	    "IDC: REGISTER on %s, depth %d\n",
+	    (char *) xmlSchemaFormatNsUriLocal(&str, vctxt->elemInfo->namespaceName,
 		vctxt->elemInfo->localName), vctxt->depth);
 	FREE_AND_NULL(str)
     }
@@ -17495,7 +17344,7 @@
 	* Init the automaton state object. 
 	*/
 	if (xmlSchemaIDCAddStateObject(vctxt, matcher, 
-	    idc->selector, NULL, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
+	    idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
 	    return (-1);
 
 	idc = idc->next;
@@ -17554,15 +17403,17 @@
 	/*
 	* Skip keyref IDCs.
 	*/
-	if (bind->definition->type == XML_SCHEMA_TYPE_IDC_KEYREF)
+	if (bind->definition->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
+	    bind = bind->next;
 	    continue;
+	}
 	/*
 	* Check if the key/unique IDC table needs to be bubbled.
 	*/
 	aidc = vctxt->aidcs;
 	do {
 	    if (aidc->def == bind->definition) {
-		if (aidc->bubbleDepth == vctxt->depth) {
+		if (aidc->bubbleDepth >= vctxt->depth) {
 		    bind = bind->next;
 		    goto start_binding;
 		}
@@ -17570,6 +17421,7 @@
 	    }
 	    aidc = aidc->next;
 	} while (aidc != NULL);
+
 	if (parTable != NULL)
 	    parBind = *parTable;
 	while (parBind != NULL) {
@@ -17752,12 +17604,9 @@
 		return(-1);
 	    }
 	    parBind->sizeNodes = bind->nbNodes;
+	    parBind->nbNodes = bind->nbNodes;
 	    memcpy(parBind->nodeTable, bind->nodeTable,
 		bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
-	    /*
-	    for (i = 1; i < bind->nbNodes; i++)
-		parBind->nodeTable[i] = bind->nodeTable[i];
-		*/
 	    if (*parTable == NULL)
 		*parTable = parBind;
 	    else
@@ -17906,13 +17755,13 @@
     * Merge/free the IDC table.
     */
     if (vctxt->elemInfo->idcTable != NULL) {
+#ifdef IDC_ENABLED
 #ifdef DEBUG_IDC
 	xmlSchemaDebugDumpIDCTable(stdout,
 	    vctxt->elemInfo->namespaceName,
 	    vctxt->elemInfo->localName,
 	    vctxt->elemInfo->idcTable);
 #endif
-#ifdef IDC_ENABLED
 	if (vctxt->depth > 0) {
 	    /*
 	    * Merge the IDC node table with the table of the parent node.
@@ -19657,6 +19506,15 @@
 		"No matching global declaration available", NULL);
 	    ret = XML_SCHEMAV_CVC_ELT_1;
 	} else { 
+#ifdef IDC_ENABLED
+	    /*
+	    * Augment the IDC definitions.
+	    */
+	    if (ctxt->schema->idcDef != NULL) {
+		xmlHashScan(ctxt->schema->idcDef, 
+		    (xmlHashScanner) xmlSchemaAugmentIDC, ctxt);
+	    }
+#endif
 #ifdef ELEM_INFO_ENABLED
 	    ctxt->depth = -1;
 	    xmlSchemaBeginElement(ctxt);
@@ -19847,7 +19705,7 @@
     if (ctxt->elemInfos != NULL) {
 	int i;
 	xmlSchemaElemInfoPtr info;
-
+	
 	for (i = 0; i < ctxt->sizeElemInfos; i++) {
 	    info = ctxt->elemInfos[i];
 	    if (info == NULL)