xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
				  xmlSchemaBasicItemPtr item,
				  xmlSchemaWildcardPtr *completeWild,
				  xmlSchemaItemListPtr list,
				  xmlSchemaItemListPtr prohibs)
{
    xmlSchemaAttributeGroupPtr gr;
    xmlSchemaAttributeUsePtr use;
    xmlSchemaItemListPtr sublist;
    int i, j;
    int created = (*completeWild == NULL) ? 0 : 1;

    if (prohibs)
	prohibs->nbItems = 0;

    for (i = 0; i < list->nbItems; i++) {
	use = list->items[i];

	if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
	    if (prohibs == NULL) {
		PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
		    "unexpected attr prohibition found");
		return(-1);
	    }
	    /*
	    * Remove from attribute uses.
	    */
	    if (xmlSchemaItemListRemove(list, i) == -1)
		return(-1);
	    i--;
	    /*
	    * Note that duplicate prohibitions were already
	    * handled at parsing time.
	    */
	    /*
	    * Add to list of prohibitions.
	    */
	    xmlSchemaItemListAddSize(prohibs, 2, use);
	    continue;
	}
	if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
	    ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
	{
	    if ((WXS_QNAME_CAST use)->item == NULL)
		return(-1);
	    gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
	    /*
	    * Expand the referenced attr. group.
	    * TODO: remove this, this is done in a previous step, so
	    * already done here.
	    */
	    if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
		if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
		    return(-1);
	    }
	    /*
	    * Build the 'complete' wildcard; i.e. intersect multiple
	    * wildcards.
	    */
	    if (gr->attributeWildcard != NULL) {
		if (*completeWild == NULL) {
		    *completeWild = gr->attributeWildcard;
		} else {
		    if (! created) {
			xmlSchemaWildcardPtr tmpWild;

			 /*
			* Copy the first encountered wildcard as context,
			* except for the annotation.
			*
			* Although the complete wildcard might not correspond
			* to any node in the schema, we will anchor it on
			* the node of the owner component.
			*/
			tmpWild =  xmlSchemaAddWildcard(pctxt, pctxt->schema,
			    XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
			    WXS_ITEM_NODE(item));
			if (tmpWild == NULL)
			    return(-1);
			if (xmlSchemaCloneWildcardNsConstraints(pctxt,
			    tmpWild, *completeWild) == -1)
			    return (-1);
			tmpWild->processContents = (*completeWild)->processContents;
			*completeWild = tmpWild;
			created = 1;
		    }

		    if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
			gr->attributeWildcard) == -1)
			return(-1);
		}
	    }
	    /*
	    * Just remove the reference if the referenced group does not
	    * contain any attribute uses.
	    */
	    sublist = ((xmlSchemaItemListPtr) gr->attrUses);
	    if ((sublist == NULL) || sublist->nbItems == 0) {
		if (xmlSchemaItemListRemove(list, i) == -1)
		    return(-1);
		i--;
		continue;
	    }
	    /*
	    * Add the attribute uses.
	    */
	    list->items[i] = sublist->items[0];
	    if (sublist->nbItems != 1) {
		for (j = 1; j < sublist->nbItems; j++) {
		    i++;
		    if (xmlSchemaItemListInsert(list,
			    sublist->items[j], i) == -1)
			return(-1);
		}
	    }
	}

    }
    /*
    * Handle pointless prohibitions of declared attributes.
    */
    if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
	xmlSchemaAttributeUseProhibPtr prohib;

	for (i = prohibs->nbItems -1; i >= 0; i--) {
	    prohib = prohibs->items[i];
	    for (j = 0; j < list->nbItems; j++) {
		use = list->items[j];

		if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
		    (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
		{
		    xmlChar *str = NULL;

		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
			XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
			prohib->node, NULL,
			"Skipping pointless attribute use prohibition "
			"'%s', since a corresponding attribute use "
			"exists already in the type definition",
			xmlSchemaFormatQName(&str,
			    prohib->targetNamespace, prohib->name),
			NULL, NULL);
		    FREE_AND_NULL(str);
		    /*
		    * Remove the prohibition.
		    */
		    if (xmlSchemaItemListRemove(prohibs, i) == -1)
			return(-1);
		    break;
		}
	    }
	}
    }
    return(0);
}