xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
{
    xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
    xmlSchemaTypePtr actualType;

    /*
    * cvc-elt (3.3.4) : 1
    */
    if (elemDecl == NULL) {
	VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
	    "No matching declaration available");
        return (vctxt->err);
    }
    actualType = WXS_ELEM_TYPEDEF(elemDecl);
    /*
    * cvc-elt (3.3.4) : 2
    */
    if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
	VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
	    "The element declaration is abstract");
        return (vctxt->err);
    }
    if (actualType == NULL) {
	VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
	    "The type definition is absent");
	return (XML_SCHEMAV_CVC_TYPE_1);
    }
    if (vctxt->nbAttrInfos != 0) {
	int ret;
	xmlSchemaAttrInfoPtr iattr;
	/*
	* cvc-elt (3.3.4) : 3
	* Handle 'xsi:nil'.
	*/
	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
	    XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
	if (iattr) {
	    ACTIVATE_ATTRIBUTE(iattr);
	    /*
	    * Validate the value.
	    */
	    ret = xmlSchemaVCheckCVCSimpleType(
		ACTXT_CAST vctxt, NULL,
		xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
		iattr->value, &(iattr->val), 1, 0, 0);
	    ACTIVATE_ELEM;
	    if (ret < 0) {
		VERROR_INT("xmlSchemaValidateElemDecl",
		    "calling xmlSchemaVCheckCVCSimpleType() to "
		    "validate the attribute 'xsi:nil'");
		return (-1);
	    }
	    if (ret == 0) {
		if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
		    /*
		    * cvc-elt (3.3.4) : 3.1
		    */
		    VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
			"The element is not 'nillable'");
		    /* Does not return an error on purpose. */
		} else {
		    if (xmlSchemaValueGetAsBoolean(iattr->val)) {
			/*
			* cvc-elt (3.3.4) : 3.2.2
			*/
			if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
			    (elemDecl->value != NULL)) {
			    VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
				"The element cannot be 'nilled' because "
				"there is a fixed value constraint defined "
				"for it");
			     /* Does not return an error on purpose. */
			} else
			    vctxt->inode->flags |=
				XML_SCHEMA_ELEM_INFO_NILLED;
		    }
		}
	    }
	}
	/*
	* cvc-elt (3.3.4) : 4
	* Handle 'xsi:type'.
	*/
	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
	    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
	if (iattr) {
	    xmlSchemaTypePtr localType = NULL;

	    ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
		elemDecl);
	    if (ret != 0) {
		if (ret == -1) {
		    VERROR_INT("xmlSchemaValidateElemDecl",
			"calling xmlSchemaProcessXSIType() to "
			"process the attribute 'xsi:type'");
		    return (-1);
		}
		/* Does not return an error on purpose. */
	    }
	    if (localType != NULL) {
		vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
		actualType = localType;
	    }
	}
    }
    /*
    * IDC: Register identity-constraint XPath matchers.
    */
    if ((elemDecl->idcs != NULL) &&
	(xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
	    return (-1);
    /*
    * No actual type definition.
    */
    if (actualType == NULL) {
	VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
	    "The type definition is absent");
	return (XML_SCHEMAV_CVC_TYPE_1);
    }
    /*
    * Remember the actual type definition.
    */
    vctxt->inode->typeDef = actualType;

    return (0);
}