xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
			xmlSchemaAttrInfoPtr iattr,
			xmlSchemaTypePtr *localType,
			xmlSchemaElementPtr elemDecl)
{
    int ret = 0;
    /*
    * cvc-elt (3.3.4) : (4)
    * AND
    * Schema-Validity Assessment (Element) (cvc-assess-elt)
    *   (1.2.1.2.1) - (1.2.1.2.4)
    * Handle 'xsi:type'.
    */
    if (localType == NULL)
	return (-1);
    *localType = NULL;
    if (iattr == NULL)
	return (0);
    else {
	const xmlChar *nsName = NULL, *local = NULL;
	/*
	* TODO: We should report a *warning* that the type was overriden
	* by the instance.
	*/
	ACTIVATE_ATTRIBUTE(iattr);
	/*
	* (cvc-elt) (3.3.4) : (4.1)
	* (cvc-assess-elt) (1.2.1.2.2)
	*/
	ret = xmlSchemaVExpandQName(vctxt, iattr->value,
	    &nsName, &local);
	if (ret != 0) {
	    if (ret < 0) {
		VERROR_INT("xmlSchemaValidateElementByDeclaration",
		    "calling xmlSchemaQNameExpand() to validate the "
		    "attribute 'xsi:type'");
		goto internal_error;
	    }
	    goto exit;
	}
	/*
	* (cvc-elt) (3.3.4) : (4.2)
	* (cvc-assess-elt) (1.2.1.2.3)
	*/
	*localType = xmlSchemaGetType(vctxt->schema, local, nsName);
	if (*localType == NULL) {
	    xmlChar *str = NULL;

	    xmlSchemaCustomErr(ACTXT_CAST vctxt,
		XML_SCHEMAV_CVC_ELT_4_2, NULL,
		WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
		"The QName value '%s' of the xsi:type attribute does not "
		"resolve to a type definition",
		xmlSchemaFormatQName(&str, nsName, local), NULL);
	    FREE_AND_NULL(str);
	    ret = vctxt->err;
	    goto exit;
	}
	if (elemDecl != NULL) {
	    int set = 0;

	    /*
	    * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
	    * "The `local type definition` must be validly
	    * derived from the {type definition} given the union of
	    * the {disallowed substitutions} and the {type definition}'s
	    * {prohibited substitutions}, as defined in
	    * Type Derivation OK (Complex) ($3.4.6)
	    * (if it is a complex type definition),
	    * or given {disallowed substitutions} as defined in Type
	    * Derivation OK (Simple) ($3.14.6) (if it is a simple type
	    * definition)."
	    *
	    * {disallowed substitutions}: the "block" on the element decl.
	    * {prohibited substitutions}: the "block" on the type def.
	    */
	    /*
	    * OPTIMIZE TODO: We could map types already evaluated
	    * to be validly derived from other types to avoid checking
	    * this over and over for the same types.
	    */
	    if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
		(elemDecl->subtypes->flags &
		    XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
		set |= SUBSET_EXTENSION;

	    if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
		(elemDecl->subtypes->flags &
		    XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
		set |= SUBSET_RESTRICTION;

	    /*
	    * REMOVED and CHANGED since this produced a parser context
	    * which adds to the string dict of the schema. So this would
	    * change the schema and we don't want this. We don't need
	    * the parser context anymore.
	    *
	    * if ((vctxt->pctxt == NULL) &&
	    *	(xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
	    *	    return (-1);
	    */

	    if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
		elemDecl->subtypes, set) != 0) {
		xmlChar *str = NULL;

		xmlSchemaCustomErr(ACTXT_CAST vctxt,
		    XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
		    "The type definition '%s', specified by xsi:type, is "
		    "blocked or not validly derived from the type definition "
		    "of the element declaration",
		    xmlSchemaFormatQName(&str,
			(*localType)->targetNamespace,
			(*localType)->name),
		    NULL);
		FREE_AND_NULL(str);
		ret = vctxt->err;
		*localType = NULL;
	    }
	}
    }
exit:
    ACTIVATE_ELEM;
    return (ret);
internal_error:
    ACTIVATE_ELEM;
    return (-1);
}