xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
				xmlSchemaPtr schema,
				xmlNodePtr node,
				int type)
{
    xmlNodePtr child = NULL;
    const xmlChar *schemaLocation = NULL;
    int res = 0; /* hasRedefinitions = 0 */
    int isChameleon = 0, wasChameleon = 0;
    xmlSchemaBucketPtr bucket = NULL;

    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
        return (-1);

    /*
    * Parse attributes. Note that the returned schemaLocation will
    * be already converted to an absolute URI.
    */
    res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
	node, (xmlChar **) (&schemaLocation), type);
    if (res != 0)
	return(res);
    /*
    * Load and add the schema document.
    */
    res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
	NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
    if (res != 0)
	return(res);
    /*
    * If we get no schema bucket back, then this means that the schema
    * document could not be located or was broken XML or was not
    * a schema document.
    */
    if ((bucket == NULL) || (bucket->doc == NULL)) {
	if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
	    /*
	    * WARNING for <include>:
	    * We will raise an error if the schema cannot be located
	    * for inclusions, since the that was the feedback from the
	    * schema people. I.e. the following spec piece will *not* be
	    * satisfied:
	    * SPEC src-include: "It is not an error for the `actual value` of the
	    * schemaLocation [attribute] to fail to resolve it all, in which
	    * case no corresponding inclusion is performed.
	    * So do we need a warning report here?"
	    */
	    res = XML_SCHEMAP_SRC_INCLUDE;
	    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
		node, NULL,
		"Failed to load the document '%s' for inclusion",
		schemaLocation, NULL);
	} else {
	    /*
	    * NOTE: This was changed to raise an error even if no redefinitions
	    * are specified.
	    *
	    * SPEC src-redefine (1)
	    * "If there are any element information items among the [children]
	    * other than <annotation> then the `actual value` of the
	    * schemaLocation [attribute] must successfully resolve."
	    * TODO: Ask the WG if a the location has always to resolve
	    * here as well!
	    */
	    res = XML_SCHEMAP_SRC_REDEFINE;
	    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
		node, NULL,
		"Failed to load the document '%s' for redefinition",
		schemaLocation, NULL);
	}
    } else {
	/*
	* Check targetNamespace sanity before parsing the new schema.
	* TODO: Note that we won't check further content if the
	* targetNamespace was bad.
	*/
	if (bucket->origTargetNamespace != NULL) {
	    /*
	    * SPEC src-include (2.1)
	    * "SII has a targetNamespace [attribute], and its `actual
	    * value` is identical to the `actual value` of the targetNamespace
	    * [attribute] of SII' (which must have such an [attribute])."
	    */
	    if (pctxt->targetNamespace == NULL) {
		xmlSchemaCustomErr(ACTXT_CAST pctxt,
		    XML_SCHEMAP_SRC_INCLUDE,
		    node, NULL,
		    "The target namespace of the included/redefined schema "
		    "'%s' has to be absent, since the including/redefining "
		    "schema has no target namespace",
		    schemaLocation, NULL);
		goto exit_error;
	    } else if (!xmlStrEqual(bucket->origTargetNamespace,
		pctxt->targetNamespace)) {
		/* TODO: Change error function. */
		xmlSchemaPCustomErrExt(pctxt,
		    XML_SCHEMAP_SRC_INCLUDE,
		    NULL, node,
		    "The target namespace '%s' of the included/redefined "
		    "schema '%s' differs from '%s' of the "
		    "including/redefining schema",
		    bucket->origTargetNamespace, schemaLocation,
		    pctxt->targetNamespace);
		goto exit_error;
	    }
	} else if (pctxt->targetNamespace != NULL) {
	    /*
	    * Chameleons: the original target namespace will
	    * differ from the resulting namespace.
	    */
	    isChameleon = 1;
	    if (bucket->parsed &&
		bucket->origTargetNamespace != NULL) {
		xmlSchemaCustomErr(ACTXT_CAST pctxt,
		    XML_SCHEMAP_SRC_INCLUDE,
		    node, NULL,
		    "The target namespace of the included/redefined schema "
		    "'%s' has to be absent or the same as the "
		    "including/redefining schema's target namespace",
		    schemaLocation, NULL);
		goto exit_error;
	    }
	    bucket->targetNamespace = pctxt->targetNamespace;
	}
    }
    /*
    * Parse the schema.
    */
    if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
	if (isChameleon) {
	    /* TODO: Get rid of this flag on the schema itself. */
	    if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
		schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
	    } else
		wasChameleon = 1;
	}
	xmlSchemaParseNewDoc(pctxt, schema, bucket);
	/* Restore chameleon flag. */
	if (isChameleon && (!wasChameleon))
	    schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
    }
    /*
    * And now for the children...
    */
    child = node->children;
    if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
	/*
	* Parse (simpleType | complexType | group | attributeGroup))*
	*/
	pctxt->redefined = bucket;
	/*
	* How to proceed if the redefined schema was not located?
	*/
	pctxt->isRedefine = 1;
	while (IS_SCHEMA(child, "annotation") ||
	    IS_SCHEMA(child, "simpleType") ||
	    IS_SCHEMA(child, "complexType") ||
	    IS_SCHEMA(child, "group") ||
	    IS_SCHEMA(child, "attributeGroup")) {
	    if (IS_SCHEMA(child, "annotation")) {
		/*
		* TODO: discard or not?
		*/
	    } else if (IS_SCHEMA(child, "simpleType")) {
		xmlSchemaParseSimpleType(pctxt, schema, child, 1);
	    } else if (IS_SCHEMA(child, "complexType")) {
		xmlSchemaParseComplexType(pctxt, schema, child, 1);
		/* hasRedefinitions = 1; */
	    } else if (IS_SCHEMA(child, "group")) {
		/* hasRedefinitions = 1; */
		xmlSchemaParseModelGroupDefinition(pctxt,
		    schema, child);
	    } else if (IS_SCHEMA(child, "attributeGroup")) {
		/* hasRedefinitions = 1; */
		xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
		    child);
	    }
	    child = child->next;
	}
	pctxt->redefined = NULL;
	pctxt->isRedefine = 0;
    } else {
	if (IS_SCHEMA(child, "annotation")) {
	    /*
	    * TODO: discard or not?
	    */
	    child = child->next;
	}
    }
    if (child != NULL) {
	res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
	if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
	    xmlSchemaPContentErr(pctxt, res,
		NULL, node, child, NULL,
		"(annotation | (simpleType | complexType | group | attributeGroup))*");
	} else {
	     xmlSchemaPContentErr(pctxt, res,
		NULL, node, child, NULL,
		"(annotation?)");
	}
    }
    return(res);

exit_error:
    return(pctxt->err);
}