Further work on IDCs, especially evaluation for attribute nodes.

* xmlschemas.c: Further work on IDCs, especially evaluation for
  attribute nodes.
diff --git a/xmlschemas.c b/xmlschemas.c
index 7e8e437..7aa5cbe 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -52,7 +52,7 @@
 
 /* #define DEBUG_UNION_VALIDATION 1 */
 
- #define ELEM_INFO_ENABLED 1 
+#define ELEM_INFO_ENABLED 1 
 
 /* #define IDC_ENABLED 1 */
 
@@ -409,6 +409,7 @@
     const xmlChar *localName;
     const xmlChar *namespaceName;
     xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
+    xmlSchemaTypePtr decl; /* the element/attribute declaration */
     xmlSchemaValPtr value; /* the pre-computed value if any */
     xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
                                             for the scope element*/
@@ -458,7 +459,8 @@
     int depth;
     xmlSchemaElemInfoPtr *elemInfos; /* array of element informations */
     int sizeElemInfos;
-    xmlSchemaElemInfoPtr elemInfo; /* the current element information */
+    xmlSchemaElemInfoPtr nodeInfo; /* the current element information */
+    xmlSchemaElemInfoPtr attrInfo; /* node infor for the current attribute */
 #endif
 #ifdef IDC_ENABLED
     xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */
@@ -2930,6 +2932,7 @@
 }
 
 #ifdef IDC_ENABLED
+#ifdef DEBUG_IDC
 /**
  * xmlSchemaDebugDumpIDCTable: 
  * @vctxt: the WXS validation context
@@ -2986,6 +2989,7 @@
 	bind = bind->next;
     } while (bind != NULL);
 }
+#endif /* DEBUG_IDC */
 #endif /* IDC_ENABLED */
 #endif /* LIBXML_OUTPUT_ENABLED */
 
@@ -5804,10 +5808,8 @@
 #ifdef IDC_ENABLED
 static int
 xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt, 
-			     xmlSchemaPtr schema,
 			     xmlSchemaIDCPtr idc,
 			     xmlSchemaIDCSelectPtr selector,
-			     xmlNodePtr parNode,
 			     xmlAttrPtr attr,
 			     int isField)
 {
@@ -5839,14 +5841,51 @@
 	    "The XPath expression of the selector is not valid", NULL);
 	return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
     } else {
+	const xmlChar **nsArray = NULL;
+	xmlNsPtr *nsList = NULL;
 	/*
 	* Compile the XPath expression.
 	*/
 	/*
 	* TODO: We need the array of in-scope namespaces for compilation.
-	*/	
-	selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
-	    NULL, 0, NULL);
+	* TODO: Call xmlPatterncompile with different options for selector/
+	* field.
+	*/
+	nsList = xmlGetNsList(attr->doc, attr->parent);
+	/*
+	* Build an array of prefixes and namespaces.
+	*/
+	if (nsList != NULL) {
+	    int i, count = 0;
+	    xmlNsPtr ns;
+
+	    for (i = 0; nsList[i] != NULL; i++)
+		count++;
+
+	    nsArray = (const xmlChar **) xmlMalloc(
+		(count * 2 + 1) * sizeof(const xmlChar *));
+	    if (nsArray == NULL) {
+		xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
+		    NULL);
+		return (-1);
+	    }
+	    for (i = 0; i < count; i++) {
+		ns = nsList[i];
+		nsArray[2 * i] = nsList[i]->href;
+		nsArray[2 * i + 1] = nsList[i]->prefix;
+	    }
+	    nsArray[count * 2] = NULL;
+	    xmlFree(nsList);
+	}
+	if (isField)
+	    selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
+		NULL, 0, nsArray);
+	else
+	    selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
+		NULL, 0, nsArray);
+	if (nsArray != NULL)
+	    xmlFree((xmlChar **) nsArray);
+	
 #ifdef IDC_XPATH_SUPPORT
 	if (selector->xpathComp == NULL) {
 	    xmlSchemaPCustomErr(ctxt,
@@ -5956,9 +5995,8 @@
 	* URGENT TODO: "field"s have an other syntax than "selector"s.
 	*/
 
-	if (xmlSchemaCheckCSelectorXPath(ctxt, schema, 
-	    idc, item, node, attr, isField) == -1) 
-	{
+	if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
+	    isField) == -1) {
 	    xmlSchemaPErr(ctxt, 
 		(xmlNodePtr) attr, 
 		XML_SCHEMAP_INTERNAL,		
@@ -6191,7 +6229,7 @@
     int minOccurs, maxOccurs;
     int isRef = 0;
 #ifdef IDC_ENABLED
-    xmlSchemaIDCPtr curIDC, lastIDC = NULL;
+    xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
 #endif
 
     /* 3.3.3 Constraints on XML Representations of Element Declarations */
@@ -6548,7 +6586,7 @@
 	    if (lastIDC != NULL)
 		lastIDC->next = curIDC;
 	    else
-		(xmlSchemaIDCPtr) ret->idcs = curIDC;
+		ret->idcs = (void *) curIDC;
 	    lastIDC = curIDC;
 #else
 	    TODO
@@ -14988,7 +15026,7 @@
 					  int valSimpleContent);
 
 static void xmlSchemaBeginElement(xmlSchemaValidCtxtPtr vctxt);
-static void xmlSchemaEndElement(xmlSchemaValidCtxtPtr vctxt);
+static int xmlSchemaEndElement(xmlSchemaValidCtxtPtr vctxt);
 
 #ifdef ELEM_INFO_ENABLED
 /**
@@ -15001,13 +15039,14 @@
  * Returns the element info item or NULL on API or internal errors.
  */
 static xmlSchemaElemInfoPtr
-xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
+xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt,
+			  int depth)
 {
     xmlSchemaElemInfoPtr info = NULL;
     
-    if (vctxt->depth > vctxt->sizeElemInfos) {
+    if (depth > vctxt->sizeElemInfos) {
 	xmlSchemaVErr(vctxt, NULL, XML_SCHEMAV_INTERNAL,
-	    "Internal error: xmlSchemaPushDepthInfo, "
+	    "Internal error: xmlSchemaGetFreshElemInfo, "
 	    "an inconsistent depth encountered.\n",
 	    NULL, NULL);
 	return (NULL);
@@ -15041,7 +15080,7 @@
 	for (; i < vctxt->sizeElemInfos; i++)
 	    vctxt->elemInfos[i] = NULL;
     } else
-	info = vctxt->elemInfos[vctxt->depth];
+	info = vctxt->elemInfos[depth];
 
     if (info == NULL) {
 	info = (xmlSchemaElemInfoPtr) 
@@ -15051,10 +15090,10 @@
 		"allocating an element info", NULL);
 	    return (NULL);
 	}	
-	vctxt->elemInfos[vctxt->depth] = info;
+	vctxt->elemInfos[depth] = info;
     }
     memset(info, 0, sizeof(xmlSchemaElemInfo));
-    info->depth = vctxt->depth;
+    info->depth = depth;
   
     return (info);
 }
@@ -15765,6 +15804,22 @@
 	    xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
 		"Internal error: xmlSchemaValidateSimpleTypeValue, "
 		"validating built-in type '%s'\n", type->name, NULL);
+	} else if ((ctxt->value == NULL) && 
+	    (type->builtInType == XML_SCHEMAS_STRING) &&
+	    (ctxt->nodeInfo != NULL) &&
+	    (ctxt->nodeInfo->flags & XML_SCHEMA_ELEM_INFO_VALUE_NEEDED)) {
+#ifdef IDC_VALUE_SUPPORT
+	    xmlChar *valdup;
+	    /*
+	    * Create a precomputed string value for "string" as well if
+	    * requested.
+	    */
+	    valdup = xmlStrdup(value);
+	    ctxt->value = xmlSchemaNewStringValue(XML_SCHEMAS_STRING,
+		BAD_CAST valdup);
+	    if ((valdup != NULL) && (ctxt->value == NULL))
+		xmlFree(valdup);
+#endif
 	}
     } else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) {        
 	/* 1.2.1 if {variety} is ·atomic· then the string must ·match· 
@@ -16443,6 +16498,7 @@
  * Frees an IDC binding. Note that the node table-items
  * are not freed.
  */
+static void
 xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
 {
     if (bind->nodeTable != NULL) {
@@ -16518,13 +16574,12 @@
  * Returns 1 if they are equal, 0 if not and -1 on internal errors.
  */
 static int
-xmlSchemaAreValuesEqual(xmlSchemaTypePtr ta,
+xmlSchemaAreValuesEqual(xmlSchemaValidCtxtPtr vctxt,
+			xmlSchemaTypePtr ta,
 			xmlSchemaValPtr a,
 			xmlSchemaTypePtr tb,
 			xmlSchemaValPtr b) 
-{   
-    int typeEqual = 0;
-    
+{       
     /* Same user derived/built-in derived/built-in primitive types. */
     if (ta == tb)
 	goto compareValue;
@@ -16582,15 +16637,16 @@
 #ifdef IDC_VALUE_SUPPORT
 	int ret;
 	ret = xmlSchemaCompareValues(a, b);
-	/*
-	* ret = xmlSchemaCompareValuesOpt(a, b,
-	*    XML_SCHEMA_VALUECOMP_STRISNORM);
-	*/
 	if (ret == 0) 
 	    return(1);
-	else if (ret == -2)
+	else if (ret == -2) {
+	    xmlSchemaVErr(vctxt, vctxt->node,
+		XML_SCHEMAV_INTERNAL,
+		"Internal error: xmlSchemaAreValuesEqual, "
+		"failed to compare the values.\n",
+		NULL, NULL);
 	    return(-1);
-	else
+	} else
 	    return(0);
 #else
 	return (1);
@@ -16690,22 +16746,23 @@
  */
 static int
 xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
-		       const xmlChar *namespaceName,
-		       const xmlChar *localName,
 		       xmlElementType nodeType)
 {
     xmlSchemaIDCStateObjPtr sto, head = NULL, first;
-    int res, resolved = 0;
+    int res, resolved = 0, depth = vctxt->depth;
         
     if (vctxt->xpathStates == NULL)
 	return (0);
+
+    if (nodeType == XML_ATTRIBUTE_NODE)
+	depth++;
 #if DEBUG_IDC
     {
 	xmlChar *str = NULL;
 	xmlGenericError(xmlGenericErrorContext, 
 	    "IDC: EVAL on %s, depth %d, type %d\n",	    
-	    xmlSchemaFormatNsUriLocal(&str, namespaceName,
-		localName), vctxt->depth, nodeType);
+	    xmlSchemaFormatNsUriLocal(&str, vctxt->nodeInfo->namespaceName,
+		vctxt->nodeInfo->localName), depth, nodeType);
 	FREE_AND_NULL(str)
     }
 #endif
@@ -16725,8 +16782,13 @@
 #endif
 
 #ifdef IDC_XPATH_SUPPORT
-	res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
-	    localName, namespaceName);	    
+	if (nodeType == XML_ELEMENT_NODE)
+	    res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
+		vctxt->nodeInfo->localName, vctxt->nodeInfo->namespaceName);
+	else
+	    res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
+		vctxt->nodeInfo->localName, vctxt->nodeInfo->namespaceName);
+
 #else
 	res = 0;
 #endif	
@@ -16768,7 +16830,7 @@
 		return(-1);
 	    }
 	}		
-	sto->history[sto->nbHistory++] = vctxt->depth;
+	sto->history[sto->nbHistory++] = depth;
 
 #ifdef DEBUG_IDC
 	xmlGenericError(xmlGenericErrorContext, "IDC:       push match '%d'\n",
@@ -16805,7 +16867,7 @@
 	    * needed.
 	    */
 	    if (resolved == 0)
-		vctxt->elemInfo->flags |= XML_SCHEMA_ELEM_INFO_VALUE_NEEDED;
+		vctxt->nodeInfo->flags |= XML_SCHEMA_ELEM_INFO_VALUE_NEEDED;
 	    resolved++;
 	}
 next_sto:
@@ -16834,12 +16896,12 @@
  */
 static int
 xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
-			     xmlSchemaTypePtr type,
-			     xmlSchemaValPtr *compValue)
+			     int depth)
 {
     xmlSchemaIDCStateObjPtr sto, nextsto;
     int res, matchDepth;
     xmlSchemaPSVIIDCKeyPtr key = NULL;
+    xmlSchemaTypePtr type = vctxt->nodeInfo->typeDef;
 
     if (vctxt->xpathStates == NULL)
 	return (0);
@@ -16850,8 +16912,8 @@
 	xmlChar *str = NULL;
 	xmlGenericError(xmlGenericErrorContext, 
 	    "IDC: BACK on %s, depth %d\n",
-	    xmlSchemaFormatNsUriLocal(&str, vctxt->elemInfo->namespaceName,
-		vctxt->elemInfo->localName), vctxt->depth);
+	    xmlSchemaFormatNsUriLocal(&str, vctxt->nodeInfo->namespaceName,
+		vctxt->nodeInfo->localName), vctxt->depth);
 	FREE_AND_NULL(str)
     }
 #endif    
@@ -16874,7 +16936,7 @@
 	/*
 	* Only matches at the current depth are of interest.
 	*/
-	if (matchDepth != vctxt->depth) {
+	if (matchDepth != depth) {
 	    sto = sto->next;
 	    continue;
 	}
@@ -16895,7 +16957,7 @@
 		sto->nbHistory--;
 		goto deregister_check;
 	    }
-	    if ((key == NULL) && (*compValue == NULL)) {
+	    if ((key == NULL) && (vctxt->nodeInfo->value == NULL)) {
 		/*
 		* Failed to provide the normalized value; maby
 		* the value was invalid.
@@ -16910,7 +16972,7 @@
 	    } else {
 		xmlSchemaIDCMatcherPtr matcher = sto->matcher;
 		xmlSchemaPSVIIDCKeyPtr *keySeq;
-		int pos, index;
+		int pos, idx;
 		
 		/*
 		* The key will be anchored on the matcher's list of
@@ -16919,7 +16981,7 @@
 		* depth of creation (i.e. the depth of the scope element).
 		*/		    
 		pos = sto->depth - matcher->depth;
-		index = sto->sel->index;
+		idx = sto->sel->index;
 		
 		/*
 		* Create/grow the array of key-sequences.
@@ -16970,7 +17032,7 @@
 		if (keySeq == NULL) {	
 		    goto create_sequence;
 		} else {
-		    if (keySeq[index] != NULL) {
+		    if (keySeq[idx] != NULL) {
 			/*
 			* cvc-identity-constraint:
 			* 3 For each node in the ·target node set· all
@@ -17026,8 +17088,8 @@
 		    * Consume the compiled value.
 		    */
 		    key->type = type;
-		    key->compValue = *compValue;
-		    (*compValue) = NULL;
+		    key->compValue = vctxt->nodeInfo->value;
+		    vctxt->nodeInfo->value = NULL;
 		    /*
 		    * Store the key in a global list.
 		    */
@@ -17036,7 +17098,7 @@
 			return (-1);
 		    }
 		}
-		keySeq[index] = key;		    
+		keySeq[idx] = key;		    
 	    }
 	} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
 		
@@ -17060,7 +17122,7 @@
 	    matcher = sto->matcher;
 	    idc = matcher->aidc->def;
 	    nbKeys = idc->nbFields;
-	    pos = vctxt->depth - matcher->depth;		
+	    pos = 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.
@@ -17111,19 +17173,20 @@
 	    bind = xmlSchemaIDCAquireBinding(vctxt, matcher);
 	    if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) && 
 		(bind->nbNodes != 0)) {
-		xmlSchemaPSVIIDCKeyPtr key, bkey, *bkeySeq;
+		xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
 		
 		i = 0;
+		res = 0;
 		/*
 		* Compare the key-sequences, key by key.
 		*/
 		do {
-		    bkeySeq = bind->nodeTable[i]->keys;
+		    bkeySeq = bind->nodeTable[i]->keys;		    
 		    for (j = 0; j < nbKeys; j++) {
-			key = (*keySeq)[j];
+			ckey = (*keySeq)[j];
 			bkey = bkeySeq[j];							
-			res = xmlSchemaAreValuesEqual(key->type,
-			    key->compValue, bkey->type, bkey->compValue);
+			res = xmlSchemaAreValuesEqual(vctxt, ckey->type,
+			    ckey->compValue, bkey->type, bkey->compValue);
 			if (res == -1) {
 			    return (-1);
 			} else if (res == 0)
@@ -17223,7 +17286,7 @@
 	/*
 	* Deregister state objects if they reach the depth of creation.
 	*/
-	if ((sto->nbHistory == 0) && (sto->depth == vctxt->depth)) {
+	if ((sto->nbHistory == 0) && (sto->depth == depth)) {
 #if DEBUG_IDC
 	    xmlGenericError(xmlGenericErrorContext, "IDC:   STO pop '%s'\n",
 		sto->sel->xpath);
@@ -17280,12 +17343,12 @@
 	xmlChar *str = NULL;
 	xmlGenericError(xmlGenericErrorContext, 
 	    "IDC: REGISTER on %s, depth %d\n",
-	    (char *) xmlSchemaFormatNsUriLocal(&str, vctxt->elemInfo->namespaceName,
-		vctxt->elemInfo->localName), vctxt->depth);
+	    (char *) xmlSchemaFormatNsUriLocal(&str, vctxt->nodeInfo->namespaceName,
+		vctxt->nodeInfo->localName), vctxt->depth);
 	FREE_AND_NULL(str)
     }
 #endif
-    if (vctxt->elemInfo->idcMatchers != NULL) {
+    if (vctxt->nodeInfo->idcMatchers != NULL) {
 	xmlSchemaVErr(vctxt, vctxt->node,
 	    XML_SCHEMAV_INTERNAL,
 	    "Internal error: xmlSchemaIDCRegisterMatchers: "
@@ -17356,7 +17419,7 @@
 	}
 	memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
 	if (last == NULL)
-	    vctxt->elemInfo->idcMatchers = matcher;
+	    vctxt->nodeInfo->idcMatchers = matcher;
 	else
 	    last->next = matcher;
 	last = matcher;
@@ -17394,11 +17457,11 @@
 xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
 {
     xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
-    xmlSchemaPSVIIDCBindingPtr *parTable, parBind, lastParBind; /* parent IDC bindings. */
-    xmlSchemaPSVIIDCNodePtr node, parNode; /* node-table entries. */
+    xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL, lastParBind = NULL; /* parent IDC bindings. */
+    xmlSchemaPSVIIDCNodePtr node, parNode = NULL; /* node-table entries. */
     xmlSchemaPSVIIDCKeyPtr key, parKey; /* keys of in a key-sequence. */
     xmlSchemaIDCAugPtr aidc;
-    int i, j, k, ret, oldNum, newDupls = 0;
+    int i, j, k, ret = 0, oldNum, newDupls = 0;
     int duplTop;
 
     /*
@@ -17414,7 +17477,7 @@
     *  # (last)
     *
     */
-    bind = vctxt->elemInfo->idcTable;        
+    bind = vctxt->nodeInfo->idcTable;        
     if (bind == NULL) {
 	/* Fine, no table, no bubbles. */
 	return (0);
@@ -17480,7 +17543,7 @@
 			    for (k = 0; k < bind->definition->nbFields; k++) {
 				key = node->keys[k];
 				parKey = parNode->keys[k];
-				ret = xmlSchemaAreValuesEqual(key->type, 
+				ret = xmlSchemaAreValuesEqual(vctxt, key->type, 
 				    key->compValue,
 				    parKey->type, parKey->compValue);
 				if (ret == -1) {
@@ -17513,7 +17576,7 @@
 			    key = node->keys[k];
 			    parKey = parNode->keys[k];			
 
-			    ret = xmlSchemaAreValuesEqual(key->type, 
+			    ret = xmlSchemaAreValuesEqual(vctxt, key->type, 
 				key->compValue,
 				parKey->type, parKey->compValue);
 			    if (ret == -1) {
@@ -17656,7 +17719,7 @@
 {
     xmlSchemaPSVIIDCBindingPtr refbind, bind;
 
-    refbind = vctxt->elemInfo->idcTable;
+    refbind = vctxt->nodeInfo->idcTable;
     /*
     * Find a keyref.
     */
@@ -17669,7 +17732,7 @@
 	    /*
 	    * Find the referred key/unique.
 	    */
-	    bind = vctxt->elemInfo->idcTable;
+	    bind = vctxt->nodeInfo->idcTable;
 	    do {
 		if ((xmlSchemaIDCPtr) refbind->definition->ref->item == 
 		    bind->definition)
@@ -17689,7 +17752,8 @@
 			for (k = 0; k < bind->definition->nbFields; k++) {
 			    refKey = refKeys[k];
 			    key = keys[k];
-			    res = xmlSchemaAreValuesEqual(key->type, key->compValue,
+			    res = xmlSchemaAreValuesEqual(vctxt,
+				key->type, key->compValue,
 				refKey->type, refKey->compValue);
 			    if (res == 0)
 				break;
@@ -17733,13 +17797,13 @@
 xmlSchemaBeginElement(xmlSchemaValidCtxtPtr vctxt)
 {
     vctxt->depth++;
-    vctxt->elemInfo = xmlSchemaGetFreshElemInfo(vctxt);
-    vctxt->elemInfo->node = vctxt->node;
-    vctxt->elemInfo->localName = vctxt->node->name;
+    vctxt->nodeInfo = xmlSchemaGetFreshElemInfo(vctxt, vctxt->depth);
+    vctxt->nodeInfo->node = vctxt->node;
+    vctxt->nodeInfo->localName = vctxt->node->name;
     if (vctxt->node->ns != NULL)
-	vctxt->elemInfo->namespaceName = vctxt->node->ns->href;
+	vctxt->nodeInfo->namespaceName = vctxt->node->ns->href;
     else 
-	vctxt->elemInfo->namespaceName = NULL;    
+	vctxt->nodeInfo->namespaceName = NULL;    
 }
 
 /**
@@ -17749,24 +17813,24 @@
  * Just a temporary workaround to simulate streaming validation
  * a bit.
  */
-static void
+static int
 xmlSchemaEndElement(xmlSchemaValidCtxtPtr vctxt)
 {
     if (vctxt->depth < 0) {
 	/* TODO: raise error? */
 	vctxt->depth--;
-	return;
+	return (0);
     }
 #ifdef IDC_ENABLED
     /*
     * Evaluate the history of changes of active state objects.
     */
-    xmlSchemaXPathProcessHistory(vctxt, vctxt->elemInfo->typeDef,
-	&(vctxt->elemInfo->value));
+    if (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1)
+	return (-1);
 
-    if (vctxt->elemInfo->value != NULL) {
-	xmlSchemaFreeValue(vctxt->elemInfo->value);
-	vctxt->elemInfo->value = NULL;
+    if (vctxt->nodeInfo->value != NULL) {
+	xmlSchemaFreeValue(vctxt->nodeInfo->value);
+	vctxt->nodeInfo->value = NULL;
     }
     /*
     * TODO: 6 The element information item must be ·valid· with respect to each of 
@@ -17782,13 +17846,13 @@
     /*
     * Merge/free the IDC table.
     */
-    if (vctxt->elemInfo->idcTable != NULL) {
+    if (vctxt->nodeInfo->idcTable != NULL) {
 #ifdef IDC_ENABLED
 #ifdef DEBUG_IDC
 	xmlSchemaDebugDumpIDCTable(stdout,
-	    vctxt->elemInfo->namespaceName,
-	    vctxt->elemInfo->localName,
-	    vctxt->elemInfo->idcTable);
+	    vctxt->nodeInfo->namespaceName,
+	    vctxt->nodeInfo->localName,
+	    vctxt->nodeInfo->idcTable);
 #endif
 	if (vctxt->depth > 0) {
 	    /*
@@ -17800,18 +17864,18 @@
 	* TODO: Don't free the PSVI IDC tables if they are
 	* requested for the PSVI.
 	*/
-	xmlSchemaIDCFreeIDCTable(vctxt->elemInfo->idcTable);
+	xmlSchemaIDCFreeIDCTable(vctxt->nodeInfo->idcTable);
 #endif
-	vctxt->elemInfo->idcTable = NULL;
+	vctxt->nodeInfo->idcTable = NULL;
     }
 
     /*
     * Cleanup IDC matchers.
     */
 #ifdef IDC_ENABLED
-    if (vctxt->elemInfo->idcMatchers != NULL) {	
-	xmlSchemaIDCFreeMatcherList(vctxt->elemInfo->idcMatchers);
-	vctxt->elemInfo->idcMatchers = NULL;
+    if (vctxt->nodeInfo->idcMatchers != NULL) {	
+	xmlSchemaIDCFreeMatcherList(vctxt->nodeInfo->idcMatchers);
+	vctxt->nodeInfo->idcMatchers = NULL;
     }
 #endif
 
@@ -17820,7 +17884,7 @@
     */
     if (vctxt->depth == 0) {
 	vctxt->depth--;
-	return;
+	return (0);
     }
 
     /*
@@ -17846,12 +17910,14 @@
     /*
     * Clear the current elemInfo.
     */
-    if (vctxt->elemInfo->value != NULL) {
-	xmlSchemaFreeValue(vctxt->elemInfo->value);
-	vctxt->elemInfo->value = NULL;
+    if (vctxt->nodeInfo->value != NULL) {
+	xmlSchemaFreeValue(vctxt->nodeInfo->value);
+	vctxt->nodeInfo->value = NULL;
     }
-    vctxt->elemInfo = vctxt->elemInfos[vctxt->depth];
-    vctxt->node = vctxt->elemInfo->node;
+    vctxt->nodeInfo = vctxt->elemInfos[vctxt->depth];
+    vctxt->node = vctxt->nodeInfo->node;
+
+    return (0);
 }
 
 #endif /* ELEM_INFO_ENABLED */
@@ -17907,8 +17973,7 @@
 	* Evaluate IDCs even if an error occured.
 	*/
 #ifdef IDC_ENABLED
-	if (xmlSchemaXPathEvaluate(ctxt, ctxt->elemInfo->namespaceName,
-	    ctxt->elemInfo->localName, XML_ELEMENT_NODE) == -1)
+	if (xmlSchemaXPathEvaluate(ctxt, XML_ELEMENT_NODE) == -1)
 	    return (-1);
 #endif
         return (ctxt->err);
@@ -17925,8 +17990,7 @@
 	* Evaluate IDCs even if an error occured.
 	*/
 #ifdef IDC_ENABLED
-	if (xmlSchemaXPathEvaluate(ctxt, ctxt->elemInfo->namespaceName,
-	    ctxt->elemInfo->localName, XML_ELEMENT_NODE) == -1)
+	if (xmlSchemaXPathEvaluate(ctxt, XML_ELEMENT_NODE) == -1)
 	    return (-1);
 #endif
         return (ctxt->err);
@@ -18085,8 +18149,7 @@
 	* Evaluate IDCs even if an error occured.
 	*/
 #ifdef IDC_ENABLED
-	if (xmlSchemaXPathEvaluate(ctxt, ctxt->elemInfo->namespaceName,
-	    ctxt->elemInfo->localName, XML_ELEMENT_NODE) == -1)
+	if (xmlSchemaXPathEvaluate(ctxt, XML_ELEMENT_NODE) == -1)
 	    return (-1);
 #endif
     	return (XML_SCHEMAV_CVC_TYPE_1);
@@ -18096,7 +18159,7 @@
     * Remember the actual-type definition.
     */
 #ifdef ELEM_INFO_ENABLED
-    ctxt->elemInfo->typeDef = actualType;
+    ctxt->nodeInfo->typeDef = actualType;
 #endif
     
     /*
@@ -18139,8 +18202,7 @@
     /* 
     * Evaluate IDCs.
     */
-    if (xmlSchemaXPathEvaluate(ctxt, ctxt->elemInfo->namespaceName,
-	    ctxt->elemInfo->localName, XML_ELEMENT_NODE) == -1)
+    if (xmlSchemaXPathEvaluate(ctxt, XML_ELEMENT_NODE) == -1)
 	return (-1);
 #endif
     /*
@@ -18236,7 +18298,7 @@
 	*/
 #ifdef ELEM_INFO_ENABLED
 	if (ctxt->value != NULL) {
-	    ctxt->elemInfo->value = ctxt->value;
+	    ctxt->nodeInfo->value = ctxt->value;
 	    ctxt->value = NULL;
 	}
 #endif
@@ -18410,8 +18472,7 @@
 	    * Evaluate IDCs even if a validation error occured.
 	    */
 #ifdef IDC_ENABLED
-	    if (xmlSchemaXPathEvaluate(ctxt, ctxt->elemInfo->namespaceName,
-		ctxt->elemInfo->localName, XML_ELEMENT_NODE) == -1)
+	    if (xmlSchemaXPathEvaluate(ctxt,XML_ELEMENT_NODE) == -1)
 		return(-1);
 #endif
 	    return (ctxt->err);
@@ -18423,8 +18484,7 @@
 	* resolves.
 	*/
 #ifdef IDC_ENABLED
-	if (xmlSchemaXPathEvaluate(ctxt, ctxt->elemInfo->namespaceName,
-	    ctxt->elemInfo->localName, XML_ELEMENT_NODE) == -1)
+	if (xmlSchemaXPathEvaluate(ctxt, XML_ELEMENT_NODE) == -1)
 	    return(-1);
 #endif
     }
@@ -18452,8 +18512,11 @@
 		*/
 		ret = xmlSchemaValidateElementByWildcardInternal(ctxt, 
 		    wild, child);
+		if (ret == -1)
+		    return (-1);
 #ifdef ELEM_INFO_ENABLED
-		xmlSchemaEndElement(ctxt);
+		if (xmlSchemaEndElement(ctxt) == -1)
+		    return (-1);
 #endif
 		if (ret != 0)
 		    return (ret);		
@@ -18717,7 +18780,9 @@
 		    else
 			nsUri = NULL;
 		    ret = xmlRegExecPushString2(ctxt->regexp,
-			child->name, nsUri, child);		    
+			child->name, nsUri, child);
+		    if (ctxt->err == XML_SCHEMAV_INTERNAL)
+			return (-1);
 		    /*
 		    * URGENT TODO: Could we anchor an error report
 		    * here to notify of invalid elements?
@@ -19021,9 +19086,7 @@
 
 static int
 xmlSchemaCheckAttrLocallyValid(xmlSchemaValidCtxtPtr ctxt,
-			       xmlSchemaAttributePtr decl,
-			       xmlSchemaAttrStatePtr state,
-			       xmlAttrPtr attr)
+			       xmlSchemaAttrStatePtr state)
 {
     xmlChar *value;
     const xmlChar *defValue;
@@ -19031,17 +19094,18 @@
     int fixed;
     int ret;
 
-    if (decl->subtypes == NULL) {
+    if (ctxt->attrInfo->typeDef == NULL) {
 	state->state = XML_SCHEMAS_ATTR_TYPE_NOT_RESOLVED;
 	return (XML_SCHEMAS_ATTR_TYPE_NOT_RESOLVED);
     }
-    value = xmlNodeListGetString(attr->doc, attr->children, 1);
-    ctxt->node = (xmlNodePtr) attr;
-    ctxt->cur = attr->children;
+    ctxt->node = ctxt->attrInfo->node;
+    ctxt->cur = ctxt->node->children;
+    value = xmlNodeListGetString(ctxt->node->doc, ctxt->cur, 1);
+    
     /*
     * NOTE: This call also checks the content nodes for correct type.
     */
-    ret = xmlSchemaValidateSimpleTypeValue(ctxt, decl->subtypes,
+    ret = xmlSchemaValidateSimpleTypeValue(ctxt, ctxt->attrInfo->typeDef,
 	value, 1, 1, 1, 1);
     	    
     /*
@@ -19059,7 +19123,8 @@
 	*/
     } else if (ret == 0) {
 	state->state = XML_SCHEMAS_ATTR_CHECKED;
-	if (xmlSchemaGetEffectiveValueConstraint(decl, 
+	if (xmlSchemaGetEffectiveValueConstraint(
+	    (xmlSchemaAttributePtr) ctxt->attrInfo->decl, 
 	    &fixed, &defValue, &defVal) && (fixed == 1)) {
 	    /*
 	    * cvc-au : Attribute Locally Valid (Use)
@@ -19074,6 +19139,8 @@
 	    * precomputed value of the attribute; well for some types,
 	    * fallback to string comparison if no computed value 
 	    * exists.
+	    * TODO: Use the *normalized* value and the *canonical* fixed
+	    * value.
 	    */
 	    if (((ctxt->value != NULL) && 
 		(xmlSchemaCompareValues(ctxt->value, defVal) != 0)) ||
@@ -19225,7 +19292,7 @@
 		if (tmp == NULL) {
 		    xmlSchemaVErrMemory(ctxt, "registering required attributes", NULL);
 		    ctxt->node = oldnode;
-		    return (-1);
+		    goto fatal_exit;
 		}            
 		tmp->attr = NULL;
 		tmp->state = XML_SCHEMAS_ATTR_MISSING;
@@ -19252,7 +19319,7 @@
 		    xmlSchemaVErrMemory(ctxt, 
 			"registering schema specified attributes", NULL);
 		    ctxt->node = oldnode;
-		    return (-1);
+		    goto fatal_exit;
 		}            
 		tmp->attr = NULL;
 		tmp->state = XML_SCHEMAS_ATTR_DEFAULT;
@@ -19362,6 +19429,7 @@
     }    
     
     if (ctxt->attr != NULL) {
+	int valueNeeded;
 
 	/*
 	* Validate the value of the attribute.
@@ -19372,15 +19440,57 @@
 	}
 	curState = ctxt->attr;
 	while ((curState != NULL) && (curState != ctxt->attrTop->next)) {
-#ifdef IDC_ENABLED
-	    xmlSchemaTypePtr attrType;
-#endif
+	    valueNeeded = 0;
 	    switch (curState->state) {
 		case XML_SCHEMAS_ATTR_VALIDATE_VALUE:
-		    ret = xmlSchemaCheckAttrLocallyValid(ctxt,
-			curState->decl, curState, curState->attr);
+
+		    /*
+		    * Create an attribute info if needed.
+		    */
+		    if (ctxt->attrInfo == NULL) {
+			ctxt->attrInfo = (xmlSchemaElemInfoPtr) 
+			    xmlMalloc(sizeof(xmlSchemaElemInfo));
+			if (ctxt->attrInfo == NULL) {
+			    xmlSchemaVErrMemory(ctxt, 
+				"allocating an attribute info", NULL);
+			    goto fatal_exit;
+			}
+		    }
+		    /*
+		    * Init the attribute info.
+		    */
+		    ctxt->attrInfo->flags = 0;
+		    ctxt->attrInfo->node = (xmlNodePtr) curState->attr;
+		    ctxt->attrInfo->decl = (xmlSchemaTypePtr) curState->decl;
+		    ctxt->attrInfo->value = NULL;
+		    if (curState->decl != NULL)
+			ctxt->attrInfo->typeDef = curState->decl->subtypes;
+		    else
+			ctxt->attrInfo->typeDef = NULL;
+		    if (curState->attr->ns != NULL)
+			ctxt->attrInfo->namespaceName = 
+			curState->attr->ns->href;
+		    else
+			ctxt->attrInfo->namespaceName = NULL;
+		    ctxt->attrInfo->localName = curState->attr->name;
+		    
+		    ctxt->nodeInfo = ctxt->attrInfo;
+
+#ifdef IDC_ENABLED  
+		    /*
+		    * Evaluate IDCs.
+		    */
+		    if (ctxt->xpathStates != NULL) {
+			ret = xmlSchemaXPathEvaluate(ctxt,
+			    XML_ATTRIBUTE_NODE);
+			if (ret == -1)
+			    goto fatal_exit;
+		    }
+
+#endif
+		    ret = xmlSchemaCheckAttrLocallyValid(ctxt, curState);
 		    if (ret == -1)
-			return (-1);
+			goto fatal_exit;
 		    if ((ret != 0) && (ctxt->value != NULL)) {
 			xmlSchemaFreeValue(ctxt->value);
 			ctxt->value = NULL;
@@ -19392,24 +19502,17 @@
 			/*
 			* Evaluate IDCs.
 			*/
-			if (curState->attr->ns != NULL) 
-			    nsURI = curState->attr->ns->href;
-			else
-			    nsURI = NULL;
-			xmlSchemaXPathEvaluate(ctxt, nsURI, attr->name,
-			    XML_ATTRIBUTE_NODE);
-			if (curState->decl != NULL)
-			    attrType = curState->decl->subtypes;
-			else
-			    attrType = NULL;
-			xmlSchemaXPathProcessHistory(ctxt,
-			    curState->decl->subtypes,
-			    &(ctxt->value));
+			if (ctxt->value != NULL) {
+			    ctxt->attrInfo->value = ctxt->value;
+			    ctxt->value = NULL;
+			}		
+			if (xmlSchemaXPathProcessHistory(ctxt, ctxt->depth +1) == -1)
+			    goto fatal_exit;
 		    }
 		    break;
 #endif
 		default:
-		    break;		
+		    break;
 	    }
 	    curState = curState->next;
 	}
@@ -19538,17 +19641,26 @@
 	    curState = curState->next;
 	}
     }
+    ret = ctxt->err;
+    goto exit;
+
+fatal_exit:
+    ret = -1;
+
+exit:    
+
     if (defAttrStates != NULL) 
 	xmlSchemaFreeAttributeStates(defAttrStates);
 		
 #ifdef DEBUG_ATTR_VALIDATION
     if (redundant)
 	xmlGenericError(xmlGenericErrorContext,
-	                "xmlSchemaValidateAttributes: redundant call by type: %s\n",
-	                type->name);
+	    "xmlSchemaValidateAttributes: redundant call by "
+	    "type: %s\n", type->name);
 #endif
+    ctxt->nodeInfo = ctxt->elemInfos[ctxt->depth];
     ctxt->node = oldnode;
-    return (ctxt->err);
+    return (ret);
 }
 
 /**
@@ -19817,6 +19929,11 @@
     }
 #endif /* IDC_ENABLED */
 #ifdef ELEM_INFO_ENABLED
+    if (ctxt->attrInfo != NULL) {
+	if (ctxt->attrInfo->value != NULL)
+	    xmlSchemaFreeValue(ctxt->attrInfo->value);
+	xmlFree(ctxt->attrInfo);
+    }
     if (ctxt->elemInfos != NULL) {
 	int i;
 	xmlSchemaElemInfoPtr info;