xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
		  xmlSchemaPtr schema,
		  xmlNodePtr node,
		  xmlSchemaTypeType idcCategory,
		  const xmlChar *targetNamespace)
{
    xmlSchemaIDCPtr item = NULL;
    xmlNodePtr child = NULL;
    xmlAttrPtr attr;
    const xmlChar *name = NULL;
    xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;

    /*
    * Check for illegal attributes.
    */
    attr = node->properties;
    while (attr != NULL) {
	if (attr->ns == NULL) {
	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
		(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
		((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
		 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
		xmlSchemaPIllegalAttrErr(ctxt,
		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
	    }
	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
	    xmlSchemaPIllegalAttrErr(ctxt,
		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
	}
	attr = attr->next;
    }
    /*
    * Attribute "name" (mandatory).
    */
    attr = xmlSchemaGetPropNode(node, "name");
    if (attr == NULL) {
	xmlSchemaPMissingAttrErr(ctxt,
	    XML_SCHEMAP_S4S_ATTR_MISSING,
	    NULL, node,
	    "name", NULL);
	return (NULL);
    } else if (xmlSchemaPValAttrNode(ctxt,
	NULL, attr,
	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
	return (NULL);
    }
    /* Create the component. */
    item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
	idcCategory, node);
    if (item == NULL)
	return(NULL);

    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
    if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
	/*
	* Attribute "refer" (mandatory).
	*/
	attr = xmlSchemaGetPropNode(node, "refer");
	if (attr == NULL) {
	    xmlSchemaPMissingAttrErr(ctxt,
		XML_SCHEMAP_S4S_ATTR_MISSING,
		NULL, node,
		"refer", NULL);
	} else {
	    /*
	    * Create a reference item.
	    */
	    item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
		NULL, NULL);
	    if (item->ref == NULL)
		return (NULL);
	    xmlSchemaPValAttrNodeQName(ctxt, schema,
		NULL, attr,
		&(item->ref->targetNamespace),
		&(item->ref->name));
	    xmlSchemaCheckReference(ctxt, schema, node, attr,
		item->ref->targetNamespace);
	}
    }
    /*
    * And now for the children...
    */
    child = node->children;
    if (IS_SCHEMA(child, "annotation")) {
	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
	child = child->next;
    }
    if (child == NULL) {
	xmlSchemaPContentErr(ctxt,
		XML_SCHEMAP_S4S_ELEM_MISSING,
		NULL, node, child,
		"A child element is missing",
		"(annotation?, (selector, field+))");
    }
    /*
    * Child element <selector>.
    */
    if (IS_SCHEMA(child, "selector")) {
	item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
	    item, child, 0);
	child = child->next;
	/*
	* Child elements <field>.
	*/
	if (IS_SCHEMA(child, "field")) {
	    do {
		field = xmlSchemaParseIDCSelectorAndField(ctxt,
		    item, child, 1);
		if (field != NULL) {
		    field->index = item->nbFields;
		    item->nbFields++;
		    if (lastField != NULL)
			lastField->next = field;
		    else
			item->fields = field;
		    lastField = field;
		}
		child = child->next;
	    } while (IS_SCHEMA(child, "field"));
	} else {
	    xmlSchemaPContentErr(ctxt,
		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
		NULL, node, child,
		NULL, "(annotation?, (selector, field+))");
	}
    }
    if (child != NULL) {
	xmlSchemaPContentErr(ctxt,
	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
	    NULL, node, child,
	    NULL, "(annotation?, (selector, field+))");
    }

    return (item);
}