xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
{
    xmlSchemaNodeInfoPtr pielem;
    xmlSchemaTypePtr ptype;
    int ret = 0;

    if (vctxt->depth <= 0) {
	VERROR_INT("xmlSchemaValidateChildElem",
	    "not intended for the validation root");
	return (-1);
    }
    pielem = vctxt->elemInfos[vctxt->depth -1];
    if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
	pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
    /*
    * Handle 'nilled' elements.
    */
    if (INODE_NILLED(pielem)) {
	/*
	* SPEC (cvc-elt) (3.3.4) : (3.2.1)
	*/
	ACTIVATE_PARENT_ELEM;
	ret = XML_SCHEMAV_CVC_ELT_3_2_1;
	VERROR(ret, NULL,
	    "Neither character nor element content is allowed, "
	    "because the element was 'nilled'");
	ACTIVATE_ELEM;
	goto unexpected_elem;
    }

    ptype = pielem->typeDef;

    if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
	/*
	* Workaround for "anyType": we have currently no content model
	* assigned for "anyType", so handle it explicitely.
	* "anyType" has an unbounded, lax "any" wildcard.
	*/
	vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
	    vctxt->inode->localName,
	    vctxt->inode->nsName);

	if (vctxt->inode->decl == NULL) {
	    xmlSchemaAttrInfoPtr iattr;
	    /*
	    * Process "xsi:type".
	    * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
	    */
	    iattr = xmlSchemaGetMetaAttrInfo(vctxt,
		XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
	    if (iattr != NULL) {
		ret = xmlSchemaProcessXSIType(vctxt, iattr,
		    &(vctxt->inode->typeDef), NULL);
		if (ret != 0) {
		    if (ret == -1) {
			VERROR_INT("xmlSchemaValidateChildElem",
			    "calling xmlSchemaProcessXSIType() to "
			    "process the attribute 'xsi:nil'");
			return (-1);
		    }
		    return (ret);
		}
	    } else {
		 /*
		 * Fallback to "anyType".
		 *
		 * SPEC (cvc-assess-elt)
		 * "If the item cannot be `strictly assessed`, [...]
		 * an element information item's schema validity may be laxly
		 * assessed if its `context-determined declaration` is not
		 * skip by `validating` with respect to the `ur-type
		 * definition` as per Element Locally Valid (Type) ($3.3.4)."
		*/
		vctxt->inode->typeDef =
		    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
	    }
	}
	return (0);
    }

    switch (ptype->contentType) {
	case XML_SCHEMA_CONTENT_EMPTY:
	    /*
	    * SPEC (2.1) "If the {content type} is empty, then the
	    * element information item has no character or element
	    * information item [children]."
	    */
	    ACTIVATE_PARENT_ELEM
	    ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
	    VERROR(ret, NULL,
		"Element content is not allowed, "
		"because the content type is empty");
	    ACTIVATE_ELEM
	    goto unexpected_elem;
	    break;

	case XML_SCHEMA_CONTENT_MIXED:
        case XML_SCHEMA_CONTENT_ELEMENTS: {
	    xmlRegExecCtxtPtr regexCtxt;
	    xmlChar *values[10];
	    int terminal, nbval = 10, nbneg;

	    /* VAL TODO: Optimized "anyType" validation.*/

	    if (ptype->contModel == NULL) {
		VERROR_INT("xmlSchemaValidateChildElem",
		    "type has elem content but no content model");
		return (-1);
	    }
	    /*
	    * Safety belf for evaluation if the cont. model was already
	    * examined to be invalid.
	    */
	    if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
		VERROR_INT("xmlSchemaValidateChildElem",
		    "validating elem, but elem content is already invalid");
		return (-1);
	    }

	    regexCtxt = pielem->regexCtxt;
	    if (regexCtxt == NULL) {
		/*
		* Create the regex context.
		*/
		regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
		    (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
		    vctxt);
		if (regexCtxt == NULL) {
		    VERROR_INT("xmlSchemaValidateChildElem",
			"failed to create a regex context");
		    return (-1);
		}
		pielem->regexCtxt = regexCtxt;
#ifdef DEBUG_AUTOMATA
		xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
		    pielem->localName);
#endif
	    }

	    /*
	    * SPEC (2.4) "If the {content type} is element-only or mixed,
	    * then the sequence of the element information item's
	    * element information item [children], if any, taken in
	    * order, is `valid` with respect to the {content type}'s
	    * particle, as defined in Element Sequence Locally Valid
	    * (Particle) ($3.9.4)."
	    */
	    ret = xmlRegExecPushString2(regexCtxt,
		vctxt->inode->localName,
		vctxt->inode->nsName,
		vctxt->inode);
#ifdef DEBUG_AUTOMATA
	    if (ret < 0)
		xmlGenericError(xmlGenericErrorContext,
		"AUTOMATON push ERROR for '%s' on '%s'\n",
		vctxt->inode->localName, pielem->localName);
	    else
		xmlGenericError(xmlGenericErrorContext,
		"AUTOMATON push OK for '%s' on '%s'\n",
		vctxt->inode->localName, pielem->localName);
#endif
	    if (vctxt->err == XML_SCHEMAV_INTERNAL) {
		VERROR_INT("xmlSchemaValidateChildElem",
		    "calling xmlRegExecPushString2()");
		return (-1);
	    }
	    if (ret < 0) {
		xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
		    &values[0], &terminal);
		xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
		    XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
		    "This element is not expected",
		    nbval, nbneg, values);
		ret = vctxt->err;
		goto unexpected_elem;
	    } else
		ret = 0;
	}
	    break;
	case XML_SCHEMA_CONTENT_SIMPLE:
	case XML_SCHEMA_CONTENT_BASIC:
	    ACTIVATE_PARENT_ELEM
	    if (WXS_IS_COMPLEX(ptype)) {
		/*
		* SPEC (cvc-complex-type) (2.2)
		* "If the {content type} is a simple type definition, then
		* the element information item has no element information
		* item [children], ..."
		*/
		ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
		VERROR(ret, NULL, "Element content is not allowed, "
		    "because the content type is a simple type definition");
	    } else {
		/*
		* SPEC (cvc-type) (3.1.2) "The element information item must
		* have no element information item [children]."
		*/
		ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
		VERROR(ret, NULL, "Element content is not allowed, "
		    "because the type definition is simple");
	    }
	    ACTIVATE_ELEM
	    ret = vctxt->err;
	    goto unexpected_elem;
	    break;

	default:
	    break;
    }
    return (ret);
unexpected_elem:
    /*
    * Pop this element and set the skipDepth to skip
    * all further content of the parent element.
    */
    vctxt->skipDepth = vctxt->depth;
    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
    pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
    return (ret);
}