xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
{
    xmlSchemaIDCMatcherPtr matcher;
    xmlSchemaPSVIIDCBindingPtr bind;

    matcher = vctxt->inode->idcMatchers;
    /*
    * Find a keyref.
    */
    while (matcher != NULL) {
	if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
	    matcher->targets &&
	    matcher->targets->nbItems)
	{
	    int i, j, k, res, nbFields, hasDupls;
	    xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
	    xmlSchemaPSVIIDCNodePtr refNode = NULL;

	    nbFields = matcher->aidc->def->nbFields;

	    /*
	    * Find the IDC node-table for the referenced IDC key/unique.
	    */
	    bind = vctxt->inode->idcTable;
	    while (bind != NULL) {
		if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
		    bind->definition)
		    break;
		bind = bind->next;
	    }
	    hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
	    /*
	    * Search for a matching key-sequences.
	    */
	    for (i = 0; i < matcher->targets->nbItems; i++) {
		res = 0;
		refNode = matcher->targets->items[i];
		if (bind != NULL) {
		    refKeys = refNode->keys;
		    for (j = 0; j < bind->nbNodes; j++) {
			keys = bind->nodeTable[j]->keys;
			for (k = 0; k < nbFields; k++) {
			    res = xmlSchemaAreValuesEqual(keys[k]->val,
				refKeys[k]->val);
			    if (res == 0)
				break;
			    else if (res == -1) {
				return (-1);
			    }
			}
			if (res == 1) {
			    /*
			    * Match found.
			    */
			    break;
			}
		    }
		    if ((res == 0) && hasDupls) {
			/*
			* Search in duplicates
			*/
			for (j = 0; j < bind->dupls->nbItems; j++) {
			    keys = ((xmlSchemaPSVIIDCNodePtr)
				bind->dupls->items[j])->keys;
			    for (k = 0; k < nbFields; k++) {
				res = xmlSchemaAreValuesEqual(keys[k]->val,
				    refKeys[k]->val);
				if (res == 0)
				    break;
				else if (res == -1) {
				    return (-1);
				}
			    }
			    if (res == 1) {
				/*
				* Match in duplicates found.
				*/
				xmlChar *str = NULL, *strB = NULL;
				xmlSchemaKeyrefErr(vctxt,
				    XML_SCHEMAV_CVC_IDC, refNode,
				    (xmlSchemaTypePtr) matcher->aidc->def,
				    "More than one match found for "
				    "key-sequence %s of keyref '%s'",
				    xmlSchemaFormatIDCKeySequence(vctxt, &str,
					refNode->keys, nbFields),
				    xmlSchemaGetComponentQName(&strB,
					matcher->aidc->def));
				FREE_AND_NULL(str);
				FREE_AND_NULL(strB);
				break;
			    }
			}
		    }
		}

		if (res == 0) {
		    xmlChar *str = NULL, *strB = NULL;
		    xmlSchemaKeyrefErr(vctxt,
			XML_SCHEMAV_CVC_IDC, refNode,
			(xmlSchemaTypePtr) matcher->aidc->def,
			"No match found for key-sequence %s of keyref '%s'",
			xmlSchemaFormatIDCKeySequence(vctxt, &str,
			    refNode->keys, nbFields),
			xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
		    FREE_AND_NULL(str);
		    FREE_AND_NULL(strB);
		}
	    }
	}
	matcher = matcher->next;
    }
    /* TODO: Return an error if any error encountered. */
    return (0);
}
xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
{
    xmlSchemaIDCMatcherPtr matcher;
    xmlSchemaPSVIIDCBindingPtr bind;

    matcher = vctxt->inode->idcMatchers;
     
    while (matcher != NULL) {
	if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
	    matcher->targets &&
	    matcher->targets->nbItems)
	{
	    int i, j, k, res, nbFields, hasDupls;
	    xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
	    xmlSchemaPSVIIDCNodePtr refNode = NULL;

	    nbFields = matcher->aidc->def->nbFields;

	     
	    bind = vctxt->inode->idcTable;
	    while (bind != NULL) {
		if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
		    bind->definition)
		    break;
		bind = bind->next;
	    }
	    hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
	     
	    for (i = 0; i < matcher->targets->nbItems; i++) {
		res = 0;
		refNode = matcher->targets->items[i];
		if (bind != NULL) {
		    refKeys = refNode->keys;
		    for (j = 0; j < bind->nbNodes; j++) {
			keys = bind->nodeTable[j]->keys;
			for (k = 0; k < nbFields; k++) {
			    res = xmlSchemaAreValuesEqual(keys[k]->val,
				refKeys[k]->val);
			    if (res == 0)
				break;
			    else if (res == -1) {
				return (-1);
			    }
			}
			if (res == 1) {
			     
			    break;
			}
		    }
		    if ((res == 0) && hasDupls) {
			 
			for (j = 0; j < bind->dupls->nbItems; j++) {
			    keys = ((xmlSchemaPSVIIDCNodePtr)
				bind->dupls->items[j])->keys;
			    for (k = 0; k < nbFields; k++) {
				res = xmlSchemaAreValuesEqual(keys[k]->val,
				    refKeys[k]->val);
				if (res == 0)
				    break;
				else if (res == -1) {
				    return (-1);
				}
			    }
			    if (res == 1) {
				 
				xmlChar *str = NULL, *strB = NULL;
				xmlSchemaKeyrefErr(vctxt,
				    XML_SCHEMAV_CVC_IDC, refNode,
				    (xmlSchemaTypePtr) matcher->aidc->def,
				    "More than one match found for "
				    "key-sequence %s of keyref '%s'",
				    xmlSchemaFormatIDCKeySequence(vctxt, &str,
					refNode->keys, nbFields),
				    xmlSchemaGetComponentQName(&strB,
					matcher->aidc->def));
				FREE_AND_NULL(str);
				FREE_AND_NULL(strB);
				break;
			    }
			}
		    }
		}

		if (res == 0) {
		    xmlChar *str = NULL, *strB = NULL;
		    xmlSchemaKeyrefErr(vctxt,
			XML_SCHEMAV_CVC_IDC, refNode,
			(xmlSchemaTypePtr) matcher->aidc->def,
			"No match found for key-sequence %s of keyref '%s'",
			xmlSchemaFormatIDCKeySequence(vctxt, &str,
			    refNode->keys, nbFields),
			xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
		    FREE_AND_NULL(str);
		    FREE_AND_NULL(strB);
		}
	    }
	}
	matcher = matcher->next;
    }
     
    return (0);
}