xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
                     xmlNodePtr node)
{
    xmlNodePtr child;
    const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
    const xmlChar *thisTargetNamespace;
    xmlAttrPtr attr;
    int ret = 0;
    xmlSchemaBucketPtr bucket = NULL;

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

    /*
    * Check for illegal attributes.
    */
    attr = node->properties;
    while (attr != NULL) {
	if (attr->ns == NULL) {
	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
		(!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
		(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
		xmlSchemaPIllegalAttrErr(pctxt,
		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
	    }
	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
	    xmlSchemaPIllegalAttrErr(pctxt,
		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
	}
	attr = attr->next;
    }
    /*
    * Extract and validate attributes.
    */
    if (xmlSchemaPValAttr(pctxt, NULL, node,
	"namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
	&namespaceName) != 0) {
	xmlSchemaPSimpleTypeErr(pctxt,
	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
	    NULL, node,
	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
	    NULL, namespaceName, NULL, NULL, NULL);
	return (pctxt->err);
    }

    if (xmlSchemaPValAttr(pctxt, NULL, node,
	"schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
	&schemaLocation) != 0) {
	xmlSchemaPSimpleTypeErr(pctxt,
	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
	    NULL, node,
	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
	    NULL, schemaLocation, NULL, NULL, NULL);
	return (pctxt->err);
    }
    /*
    * And now for the children...
    */
    child = node->children;
    if (IS_SCHEMA(child, "annotation")) {
        /*
         * the annotation here is simply discarded ...
	 * TODO: really?
         */
        child = child->next;
    }
    if (child != NULL) {
	xmlSchemaPContentErr(pctxt,
	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
	    NULL, node, child, NULL,
	    "(annotation?)");
    }
    /*
    * Apply additional constraints.
    *
    * Note that it is important to use the original @targetNamespace
    * (or none at all), to rule out imports of schemas _with_ a
    * @targetNamespace if the importing schema is a chameleon schema
    * (with no @targetNamespace).
    */
    thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
    if (namespaceName != NULL) {
	/*
	* 1.1 If the namespace [attribute] is present, then its `actual value`
	* must not match the `actual value` of the enclosing <schema>'s
	* targetNamespace [attribute].
	*/
	if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
	    xmlSchemaPCustomErr(pctxt,
		XML_SCHEMAP_SRC_IMPORT_1_1,
		NULL, node,
		"The value of the attribute 'namespace' must not match "
		"the target namespace '%s' of the importing schema",
		thisTargetNamespace);
	    return (pctxt->err);
	}
    } else {
	/*
	* 1.2 If the namespace [attribute] is not present, then the enclosing
	* <schema> must have a targetNamespace [attribute].
	*/
	if (thisTargetNamespace == NULL) {
	    xmlSchemaPCustomErr(pctxt,
		XML_SCHEMAP_SRC_IMPORT_1_2,
		NULL, node,
		"The attribute 'namespace' must be existent if "
		"the importing schema has no target namespace",
		NULL);
	    return (pctxt->err);
	}
    }
    /*
    * Locate and acquire the schema document.
    */
    if (schemaLocation != NULL)
	schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
	    schemaLocation, node);
    ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
	schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
	namespaceName, &bucket);

    if (ret != 0)
	return(ret);

    /*
    * For <import>: "It is *not* an error for the application
    * schema reference strategy to fail."
    * So just don't parse if no schema document was found.
    * Note that we will get no bucket if the schema could not be
    * located or if there was no schemaLocation.
    */
    if ((bucket == NULL) && (schemaLocation != NULL)) {
	xmlSchemaCustomWarning(ACTXT_CAST pctxt,
	    XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
	    node, NULL,
	    "Failed to locate a schema at location '%s'. "
	    "Skipping the import", schemaLocation, NULL, NULL);
    }

    if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
	ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
    }

    return (ret);
}