/*
 * schemas.c : implementation of the XML Schema handling and
 *             schema validity checking
 *
 * See Copyright for the status of this software.
 *
 * Daniel Veillard <veillard@redhat.com>
 */

/*
 * TODO:
 *   - when types are redefined in includes, check that all
 *     types in the redef list are equal
 *     -> need a type equality operation.
 */
#define IN_LIBXML
#include "libxml.h"

#ifdef LIBXML_SCHEMAS_ENABLED

#include <string.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/parserInternals.h>
#include <libxml/hash.h>
#include <libxml/uri.h>

#include <libxml/xmlschemas.h>
#include <libxml/schemasInternals.h>
#include <libxml/xmlschemastypes.h>
#include <libxml/xmlautomata.h>
#include <libxml/xmlregexp.h>
#include <libxml/dict.h>

/* #define DEBUG 1 */

/* #define DEBUG_CONTENT 1 */

/* #define DEBUG_TYPE 1 */

/* #define DEBUG_CONTENT_REGEXP 1 */

/* #define DEBUG_AUTOMATA 1 */

#define UNBOUNDED (1 << 30)
#define TODO 								\
    xmlGenericError(xmlGenericErrorContext,				\
	    "Unimplemented block at %s:%d\n",				\
            __FILE__, __LINE__);

#define XML_SCHEMAS_DEFAULT_NAMESPACE (const xmlChar *)"the default namespace"

/*
 * The XML Schemas namespaces
 */
static const xmlChar *xmlSchemaNs = (const xmlChar *)
    "http://www.w3.org/2001/XMLSchema";

static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
    "http://www.w3.org/2001/XMLSchema-instance";

#define IS_SCHEMA(node, type)						\
   ((node != NULL) && (node->ns != NULL) &&				\
    (xmlStrEqual(node->name, (const xmlChar *) type)) &&		\
    (xmlStrEqual(node->ns->href, xmlSchemaNs)))

#define XML_SCHEMAS_PARSE_ERROR		1

#define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT

struct _xmlSchemaParserCtxt {
    void *userData;             /* user specific data block */
    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
    xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */
    xmlSchemaValidError err;
    int nberrors;
    xmlStructuredErrorFunc serror;

    xmlSchemaPtr topschema;	/* The main schema */
    xmlHashTablePtr namespaces;	/* Hash table of namespaces to schemas */

    xmlSchemaPtr schema;        /* The schema in use */
    const xmlChar *container;   /* the current element, group, ... */
    int counter;

    const xmlChar *URL;
    xmlDocPtr doc;
    int preserve;		/* Whether the doc should be freed  */

    const char *buffer;
    int size;

    /*
     * Used to build complex element content models
     */
    xmlAutomataPtr am;
    xmlAutomataStatePtr start;
    xmlAutomataStatePtr end;
    xmlAutomataStatePtr state;

    xmlDictPtr dict;		/* dictionnary for interned string names */
    int        includes;	/* the inclusion level, 0 for root or imports */
};


#define XML_SCHEMAS_ATTR_UNKNOWN 1
#define XML_SCHEMAS_ATTR_CHECKED 2

typedef struct _xmlSchemaAttrState xmlSchemaAttrState;
typedef xmlSchemaAttrState *xmlSchemaAttrStatePtr;
struct _xmlSchemaAttrState {
    xmlAttrPtr attr;
    int state;
};

/**
 * xmlSchemaValidCtxt:
 *
 * A Schemas validation context
 */

struct _xmlSchemaValidCtxt {
    void *userData;             /* user specific data block */
    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
    xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */
    xmlStructuredErrorFunc serror;

    xmlSchemaPtr schema;        /* The schema in use */
    xmlDocPtr doc;
    xmlParserInputBufferPtr input;
    xmlCharEncoding enc;
    xmlSAXHandlerPtr sax;
    void *user_data;

    xmlDocPtr myDoc;
    int err;
    int nberrors;

    xmlNodePtr node;
    xmlNodePtr cur;
    xmlSchemaTypePtr type;

    xmlRegExecCtxtPtr regexp;
    xmlSchemaValPtr value;

    int attrNr;
    int attrBase;
    int attrMax;
    xmlSchemaAttrStatePtr attr;
};

/*
 * These are the entries in the schemas importSchemas hash table
 */
typedef struct _xmlSchemaImport xmlSchemaImport;
typedef xmlSchemaImport *xmlSchemaImportPtr;
struct _xmlSchemaImport {
    const xmlChar *schemaLocation;
    xmlSchemaPtr schema;
};

/*
 * These are the entries associated to includes in a schemas
 */
typedef struct _xmlSchemaInclude xmlSchemaInclude;
typedef xmlSchemaInclude *xmlSchemaIncludePtr;
struct _xmlSchemaInclude {
    xmlSchemaIncludePtr next;

    const xmlChar *schemaLocation;
    xmlDocPtr doc;
};

/************************************************************************
 * 									*
 * 			Some predeclarations				*
 * 									*
 ************************************************************************/
static int xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
                                        xmlSchemaTypePtr type,
                                        const xmlChar * value);

static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
                                 xmlSchemaPtr schema,
                                 xmlNodePtr node);
/************************************************************************
 *									*
 * 			Datatype error handlers				*
 *									*
 ************************************************************************/

/**
 * xmlSchemaPErrMemory:
 * @node: a context node
 * @extra:  extra informations
 *
 * Handle an out of memory condition
 */
static void
xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
                    const char *extra, xmlNodePtr node)
{
    if (ctxt != NULL)
        ctxt->nberrors++;
    __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
                     extra);
}

/**
 * xmlSchemaPErr:
 * @ctxt: the parsing context
 * @node: the context node
 * @error: the error code
 * @msg: the error message
 * @str1: extra data
 * @str2: extra data
 * 
 * Handle a parser error
 */
static void
xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
              const char *msg, const xmlChar * str1, const xmlChar * str2)
{
    xmlGenericErrorFunc channel = NULL;
    xmlStructuredErrorFunc schannel = NULL;
    void *data = NULL;

    if (ctxt != NULL) {
        ctxt->nberrors++;
        channel = ctxt->error;
        data = ctxt->userData;
	schannel = ctxt->serror;
    }
    __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
                    error, XML_ERR_ERROR, NULL, 0,
                    (const char *) str1, (const char *) str2, NULL, 0, 0,
                    msg, str1, str2);
}

/**
 * xmlSchemaPErr2:
 * @ctxt: the parsing context
 * @node: the context node
 * @node: the current child
 * @error: the error code
 * @msg: the error message
 * @str1: extra data
 * @str2: extra data
 * 
 * Handle a parser error
 */
static void
xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
               xmlNodePtr child, int error,
               const char *msg, const xmlChar * str1, const xmlChar * str2)
{
    if (child != NULL)
        xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
    else
        xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
}

/**
 * xmlSchemaVTypeErrMemory:
 * @node: a context node
 * @extra:  extra informations
 *
 * Handle an out of memory condition
 */
static void
xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
                    const char *extra, xmlNodePtr node)
{
    if (ctxt != NULL) {
        ctxt->nberrors++;
        ctxt->err = XML_SCHEMAS_ERR_INTERNAL;
    }
    __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
                     extra);
}

/**
 * xmlSchemaVErr3:
 * @ctxt: the validation context
 * @node: the context node
 * @error: the error code
 * @msg: the error message
 * @str1: extra data
 * @str2: extra data
 * @str3: extra data
 * 
 * Handle a validation error
 */
static void
xmlSchemaVErr3(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node, int error,
               const char *msg, const xmlChar *str1, const xmlChar *str2,
	       const xmlChar *str3)
{
    xmlStructuredErrorFunc schannel = NULL;
    xmlGenericErrorFunc channel = NULL;
    void *data = NULL;

    if (ctxt != NULL) {
        ctxt->nberrors++;
	ctxt->err = error;
        channel = ctxt->error;
        schannel = ctxt->serror;
        data = ctxt->userData;
    }
    /* reajust to global error numbers */
    error += XML_SCHEMAV_NOROOT - XML_SCHEMAS_ERR_NOROOT;
    __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASV,
                    error, XML_ERR_ERROR, NULL, 0,
                    (const char *) str1, (const char *) str2,
		    (const char *) str3, 0, 0,
                    msg, str1, str2, str3);
}
/**
 * xmlSchemaVErr:
 * @ctxt: the validation context
 * @node: the context node
 * @error: the error code
 * @msg: the error message
 * @str1: extra data
 * @str2: extra data
 * 
 * Handle a validation error
 */
static void
xmlSchemaVErr(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node, int error,
              const char *msg, const xmlChar * str1, const xmlChar * str2)
{
    xmlStructuredErrorFunc schannel = NULL;
    xmlGenericErrorFunc channel = NULL;
    void *data = NULL;

    if (ctxt != NULL) {
        ctxt->nberrors++;
	ctxt->err = error;
        channel = ctxt->error;
        data = ctxt->userData;
        schannel = ctxt->serror;
    }
    /* reajust to global error numbers */
    error += XML_SCHEMAV_NOROOT - XML_SCHEMAS_ERR_NOROOT;
    __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASV,
                    error, XML_ERR_ERROR, NULL, 0,
                    (const char *) str1, (const char *) str2, NULL, 0, 0,
                    msg, str1, str2);
}

/************************************************************************
 * 									*
 * 			Allocation functions				*
 * 									*
 ************************************************************************/

/**
 * xmlSchemaNewSchema:
 * @ctxt:  a schema validation context
 *
 * Allocate a new Schema structure.
 *
 * Returns the newly allocated structure or NULL in case or error
 */
static xmlSchemaPtr
xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
{
    xmlSchemaPtr ret;

    ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
    if (ret == NULL) {
        xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchema));
    xmlDictReference(ctxt->dict);
    ret->dict = ctxt->dict;

    return (ret);
}

/**
 * xmlSchemaNewFacet:
 *
 * Allocate a new Facet structure.
 *
 * Returns the newly allocated structure or NULL in case or error
 */
xmlSchemaFacetPtr
xmlSchemaNewFacet(void)
{
    xmlSchemaFacetPtr ret;

    ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
    if (ret == NULL) {
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchemaFacet));

    return (ret);
}

/**
 * xmlSchemaNewAnnot:
 * @ctxt:  a schema validation context
 * @node:  a node
 *
 * Allocate a new annotation structure.
 *
 * Returns the newly allocated structure or NULL in case or error
 */
static xmlSchemaAnnotPtr
xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
{
    xmlSchemaAnnotPtr ret;

    ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
    if (ret == NULL) {
        xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchemaAnnot));
    ret->content = node;
    return (ret);
}

/**
 * xmlSchemaFreeAnnot:
 * @annot:  a schema type structure
 *
 * Deallocate a annotation structure
 */
static void
xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
{
    if (annot == NULL)
        return;
    xmlFree(annot);
}

/**
 * xmlSchemaFreeImport:
 * @import:  a schema import structure
 *
 * Deallocate an import structure
 */
static void
xmlSchemaFreeImport(xmlSchemaImportPtr import)
{
    if (import == NULL)
        return;

    xmlSchemaFree(import->schema);
    xmlFree(import);
}

/**
 * xmlSchemaFreeInclude:
 * @include:  a schema include structure
 *
 * Deallocate an include structure
 */
static void
xmlSchemaFreeInclude(xmlSchemaIncludePtr include)
{
    if (include == NULL)
        return;

    xmlFreeDoc(include->doc);
    xmlFree(include);
}

/**
 * xmlSchemaFreeIncludeList:
 * @includes:  a schema include list
 *
 * Deallocate an include structure
 */
static void
xmlSchemaFreeIncludeList(xmlSchemaIncludePtr includes)
{
    xmlSchemaIncludePtr next;

    while (includes != NULL) {
        next = includes->next;
	xmlSchemaFreeInclude(includes);
	includes = next;
    }
}

/**
 * xmlSchemaFreeNotation:
 * @schema:  a schema notation structure
 *
 * Deallocate a Schema Notation structure.
 */
static void
xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
{
    if (nota == NULL)
        return;
    xmlFree(nota);
}

/**
 * xmlSchemaFreeAttribute:
 * @schema:  a schema attribute structure
 *
 * Deallocate a Schema Attribute structure.
 */
static void
xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
{
    if (attr == NULL)
        return;
    xmlFree(attr);
}

/**
 * xmlSchemaFreeAttributeGroup:
 * @schema:  a schema attribute group structure
 *
 * Deallocate a Schema Attribute Group structure.
 */
static void
xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attr)
{
    if (attr == NULL)
        return;
    xmlFree(attr);
}

/**
 * xmlSchemaFreeElement:
 * @schema:  a schema element structure
 *
 * Deallocate a Schema Element structure.
 */
static void
xmlSchemaFreeElement(xmlSchemaElementPtr elem)
{
    if (elem == NULL)
        return;
    if (elem->annot != NULL)
        xmlSchemaFreeAnnot(elem->annot);
    if (elem->contModel != NULL)
        xmlRegFreeRegexp(elem->contModel);
    xmlFree(elem);
}

/**
 * xmlSchemaFreeFacet:
 * @facet:  a schema facet structure
 *
 * Deallocate a Schema Facet structure.
 */
void
xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
{
    if (facet == NULL)
        return;
    if (facet->val != NULL)
        xmlSchemaFreeValue(facet->val);
    if (facet->regexp != NULL)
        xmlRegFreeRegexp(facet->regexp);
    if (facet->annot != NULL)
        xmlSchemaFreeAnnot(facet->annot);
    xmlFree(facet);
}

/**
 * xmlSchemaFreeType:
 * @type:  a schema type structure
 *
 * Deallocate a Schema Type structure.
 */
void
xmlSchemaFreeType(xmlSchemaTypePtr type)
{
    if (type == NULL)
        return;
    if (type->annot != NULL)
        xmlSchemaFreeAnnot(type->annot);
    if (type->facets != NULL) {
        xmlSchemaFacetPtr facet, next;

        facet = type->facets;
        while (facet != NULL) {
            next = facet->next;
            xmlSchemaFreeFacet(facet);
            facet = next;
        }
    }
    xmlFree(type);
}

/**
 * xmlSchemaFreeTypeList:
 * @type:  a schema type structure
 *
 * Deallocate a Schema Type structure.
 */
static void
xmlSchemaFreeTypeList(xmlSchemaTypePtr type)
{
    xmlSchemaTypePtr next;

    while (type != NULL) {
        next = type->redef;
	xmlSchemaFreeType(type);
	type = next;
    }
}

/**
 * xmlSchemaFree:
 * @schema:  a schema structure
 *
 * Deallocate a Schema structure.
 */
void
xmlSchemaFree(xmlSchemaPtr schema)
{
    if (schema == NULL)
        return;

    if (schema->notaDecl != NULL)
        xmlHashFree(schema->notaDecl,
                    (xmlHashDeallocator) xmlSchemaFreeNotation);
    if (schema->attrDecl != NULL)
        xmlHashFree(schema->attrDecl,
                    (xmlHashDeallocator) xmlSchemaFreeAttribute);
    if (schema->attrgrpDecl != NULL)
        xmlHashFree(schema->attrgrpDecl,
                    (xmlHashDeallocator) xmlSchemaFreeAttributeGroup);
    if (schema->elemDecl != NULL)
        xmlHashFree(schema->elemDecl,
                    (xmlHashDeallocator) xmlSchemaFreeElement);
    if (schema->typeDecl != NULL)
        xmlHashFree(schema->typeDecl,
                    (xmlHashDeallocator) xmlSchemaFreeTypeList);
    if (schema->groupDecl != NULL)
        xmlHashFree(schema->groupDecl,
                    (xmlHashDeallocator) xmlSchemaFreeType);
    if (schema->schemasImports != NULL)
	xmlHashFree(schema->schemasImports,
		    (xmlHashDeallocator) xmlSchemaFreeImport);
    if (schema->includes != NULL) {
        xmlSchemaFreeIncludeList((xmlSchemaIncludePtr) schema->includes);
    }
    if (schema->annot != NULL)
        xmlSchemaFreeAnnot(schema->annot);
    if (schema->doc != NULL && !schema->preserve)
        xmlFreeDoc(schema->doc);
    xmlDictFree(schema->dict);

    xmlFree(schema);
}

/************************************************************************
 * 									*
 * 			Debug functions					*
 * 									*
 ************************************************************************/

#ifdef LIBXML_OUTPUT_ENABLED

/**
 * xmlSchemaElementDump:
 * @elem:  an element
 * @output:  the file output
 *
 * Dump the element
 */
static void
xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output,
                     const xmlChar * name ATTRIBUTE_UNUSED,
                     const xmlChar * context ATTRIBUTE_UNUSED,
                     const xmlChar * namespace ATTRIBUTE_UNUSED)
{
    if (elem == NULL)
        return;

    fprintf(output, "Element ");
    if (elem->flags & XML_SCHEMAS_ELEM_TOPLEVEL)
        fprintf(output, "toplevel ");
    fprintf(output, ": %s ", elem->name);
    if (namespace != NULL)
        fprintf(output, "namespace '%s' ", namespace);

    if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
        fprintf(output, "nillable ");
    if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
        fprintf(output, "global ");
    if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
        fprintf(output, "default ");
    if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
        fprintf(output, "fixed ");
    if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
        fprintf(output, "abstract ");
    if (elem->flags & XML_SCHEMAS_ELEM_REF)
        fprintf(output, "ref '%s' ", elem->ref);
    if (elem->id != NULL)
        fprintf(output, "id '%s' ", elem->id);
    fprintf(output, "\n");
    if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
        fprintf(output, "  ");
        if (elem->minOccurs != 1)
            fprintf(output, "min: %d ", elem->minOccurs);
        if (elem->maxOccurs >= UNBOUNDED)
            fprintf(output, "max: unbounded\n");
        else if (elem->maxOccurs != 1)
            fprintf(output, "max: %d\n", elem->maxOccurs);
        else
            fprintf(output, "\n");
    }
    if (elem->namedType != NULL) {
        fprintf(output, "  type: %s", elem->namedType);
        if (elem->namedTypeNs != NULL)
            fprintf(output, " ns %s\n", elem->namedTypeNs);
        else
            fprintf(output, "\n");
    }
    if (elem->substGroup != NULL) {
        fprintf(output, "  substitutionGroup: %s", elem->substGroup);
        if (elem->substGroupNs != NULL)
            fprintf(output, " ns %s\n", elem->substGroupNs);
        else
            fprintf(output, "\n");
    }
    if (elem->value != NULL)
        fprintf(output, "  default: %s", elem->value);
}

/**
 * xmlSchemaAnnotDump:
 * @output:  the file output
 * @annot:  a annotation
 *
 * Dump the annotation
 */
static void
xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
{
    xmlChar *content;

    if (annot == NULL)
        return;

    content = xmlNodeGetContent(annot->content);
    if (content != NULL) {
        fprintf(output, "  Annot: %s\n", content);
        xmlFree(content);
    } else
        fprintf(output, "  Annot: empty\n");
}

/**
 * xmlSchemaTypeDump:
 * @output:  the file output
 * @type:  a type structure
 *
 * Dump a SchemaType structure
 */
static void
xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
{
    if (type == NULL) {
        fprintf(output, "Type: NULL\n");
        return;
    }
    fprintf(output, "Type: ");
    if (type->name != NULL)
        fprintf(output, "%s, ", type->name);
    else
        fprintf(output, "no name");
    switch (type->type) {
        case XML_SCHEMA_TYPE_BASIC:
            fprintf(output, "basic ");
            break;
        case XML_SCHEMA_TYPE_SIMPLE:
            fprintf(output, "simple ");
            break;
        case XML_SCHEMA_TYPE_COMPLEX:
            fprintf(output, "complex ");
            break;
        case XML_SCHEMA_TYPE_SEQUENCE:
            fprintf(output, "sequence ");
            break;
        case XML_SCHEMA_TYPE_CHOICE:
            fprintf(output, "choice ");
            break;
        case XML_SCHEMA_TYPE_ALL:
            fprintf(output, "all ");
            break;
        case XML_SCHEMA_TYPE_UR:
            fprintf(output, "ur ");
            break;
        case XML_SCHEMA_TYPE_RESTRICTION:
            fprintf(output, "restriction ");
            break;
        case XML_SCHEMA_TYPE_EXTENSION:
            fprintf(output, "extension ");
            break;
        default:
            fprintf(output, "unknowntype%d ", type->type);
            break;
    }
    if (type->base != NULL) {
        fprintf(output, "base %s, ", type->base);
    }
    switch (type->contentType) {
        case XML_SCHEMA_CONTENT_UNKNOWN:
            fprintf(output, "unknown ");
            break;
        case XML_SCHEMA_CONTENT_EMPTY:
            fprintf(output, "empty ");
            break;
        case XML_SCHEMA_CONTENT_ELEMENTS:
            fprintf(output, "element ");
            break;
        case XML_SCHEMA_CONTENT_MIXED:
            fprintf(output, "mixed ");
            break;
        case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
            fprintf(output, "mixed_or_elems ");
            break;
        case XML_SCHEMA_CONTENT_BASIC:
            fprintf(output, "basic ");
            break;
        case XML_SCHEMA_CONTENT_SIMPLE:
            fprintf(output, "simple ");
            break;
        case XML_SCHEMA_CONTENT_ANY:
            fprintf(output, "any ");
            break;
    }
    fprintf(output, "\n");
    if ((type->minOccurs != 1) || (type->maxOccurs != 1)) {
        fprintf(output, "  ");
        if (type->minOccurs != 1)
            fprintf(output, "min: %d ", type->minOccurs);
        if (type->maxOccurs >= UNBOUNDED)
            fprintf(output, "max: unbounded\n");
        else if (type->maxOccurs != 1)
            fprintf(output, "max: %d\n", type->maxOccurs);
        else
            fprintf(output, "\n");
    }
    if (type->annot != NULL)
        xmlSchemaAnnotDump(output, type->annot);
    if (type->subtypes != NULL) {
        xmlSchemaTypePtr sub = type->subtypes;

        fprintf(output, "  subtypes: ");
        while (sub != NULL) {
            fprintf(output, "%s ", sub->name);
            sub = sub->next;
        }
        fprintf(output, "\n");
    }

}

/**
 * xmlSchemaDump:
 * @output:  the file output
 * @schema:  a schema structure
 *
 * Dump a Schema structure.
 */
void
xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
{
    if (schema == NULL) {
        fprintf(output, "Schemas: NULL\n");
        return;
    }
    fprintf(output, "Schemas: ");
    if (schema->name != NULL)
        fprintf(output, "%s, ", schema->name);
    else
        fprintf(output, "no name, ");
    if (schema->targetNamespace != NULL)
        fprintf(output, "%s", (const char *) schema->targetNamespace);
    else
        fprintf(output, "no target namespace");
    fprintf(output, "\n");
    if (schema->annot != NULL)
        xmlSchemaAnnotDump(output, schema->annot);

    xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump,
                output);
    xmlHashScanFull(schema->elemDecl,
                    (xmlHashScannerFull) xmlSchemaElementDump, output);
}
#endif /* LIBXML_OUTPUT_ENABLED */

/************************************************************************
 *									*
 * 			Utilities					*
 *									*
 ************************************************************************/

/**
 * xmlSchemaGetProp:
 * @ctxt: the parser context
 * @node: the node
 * @name: the property name
 * 
 * Read a attribute value and internalize the string
 *
 * Returns the string or NULL if not present.
 */
static const xmlChar *
xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
                 const char *name)
{
    xmlChar *val;
    const xmlChar *ret;

    val = xmlGetProp(node, BAD_CAST name);
    if (val == NULL)
        return(NULL);
    ret = xmlDictLookup(ctxt->dict, val, -1);
    xmlFree(val);
    return(ret);
}

/**
 * xmlSchemaGetNamespace:
 * @ctxt: the parser context
 * @schema: the schemas containing the declaration
 * @node: the node
 * @qname: the QName to analyze
 * 
 * Find the namespace name for the given declaration.
 *
 * Returns the local name for that declaration, as well as the namespace name
 */
static const xmlChar *
xmlSchemaGetNamespace(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
	              xmlNodePtr node, const xmlChar *qname,
	     const xmlChar **namespace) {
    int len;
    const xmlChar *name, *prefix, *def = NULL;
    xmlNsPtr ns;

    *namespace = NULL;
    
    if (xmlStrEqual(node->name, BAD_CAST "element") ||
        xmlStrEqual(node->name, BAD_CAST "attribute") ||
	xmlStrEqual(node->name, BAD_CAST "simpleType") ||
	xmlStrEqual(node->name, BAD_CAST "complexType")) {
	def = xmlSchemaGetProp(ctxt, node, "targetNamespace");
    }

    qname = xmlDictLookup(ctxt->dict, qname, -1); /* intern the string */
    name = xmlSplitQName3(qname, &len);
    if (name == NULL) {
        if (def == NULL) {
	    if (xmlStrEqual(node->name, BAD_CAST "element")) {
		if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
		    *namespace = schema->targetNamespace;
	    } else if (xmlStrEqual(node->name, BAD_CAST "attribute")) {
		if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
		    *namespace = schema->targetNamespace;
	    } else if ((xmlStrEqual(node->name, BAD_CAST "simpleType")) ||
	               (xmlStrEqual(node->name, BAD_CAST "complexType"))) {
		*namespace = schema->targetNamespace;
	    }
	} else {
	    *namespace = def;
	}
	return(qname);
    }
    name = xmlDictLookup(ctxt->dict, name, -1);
    prefix = xmlDictLookup(ctxt->dict, qname, len);
    if (def != NULL) {
        xmlSchemaPErr(ctxt, node, XML_SCHEMAP_DEF_AND_PREFIX,
                      "%s: presence of both prefix %s and targetNamespace\n",
                      node->name, prefix);
    }
    ns = xmlSearchNs(node->doc, node, prefix);
    if (ns == NULL) {
        xmlSchemaPErr(ctxt, node, XML_SCHEMAP_PREFIX_UNDEFINED,
                      "%s: the QName prefix %s is undefined\n",
                      node->name, prefix);
	return(name);
    }
    *namespace = xmlDictLookup(ctxt->dict, ns->href, -1);
    return(name);
}

/************************************************************************
 * 									*
 * 			Parsing functions				*
 * 									*
 ************************************************************************/

/**
 * xmlSchemaGetElem:
 * @schema:  the schemas context
 * @name:  the element name
 * @ns:  the element namespace
 * @level: how deep is the request
 *
 * Lookup a an element in the schemas or the accessible schemas
 *
 * Returns the element definition or NULL if not found.
 */
static xmlSchemaElementPtr
xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
                 const xmlChar * namespace, int level)
{
    xmlSchemaElementPtr ret;
    xmlSchemaImportPtr import = NULL;

    if ((name == NULL) || (schema == NULL))
        return (NULL);
    
    if (namespace == NULL) {
        ret = xmlHashLookup2(schema->elemDecl, name, namespace);
        if ((ret != NULL) &&
	    ((level == 0) || (ret->flags & XML_SCHEMAS_ELEM_TOPLEVEL))) {
            return (ret);
	}
    } else if ((schema->flags & XML_SCHEMAS_QUALIF_ELEM) == 0) {
        if (xmlStrEqual(namespace, schema->targetNamespace))
	    ret = xmlHashLookup2(schema->elemDecl, name, NULL);
	else
	    ret = xmlHashLookup2(schema->elemDecl, name, namespace);
        if ((ret != NULL) &&
	    ((level == 0) || (ret->flags & XML_SCHEMAS_ELEM_TOPLEVEL))) {
            return (ret);
	}
    } else {
	ret = xmlHashLookup2(schema->elemDecl, name, namespace);
        if ((ret != NULL) &&
	    ((level == 0) || (ret->flags & XML_SCHEMAS_ELEM_TOPLEVEL))) {
            return (ret);
	}
    }
    if (level > 0)
    import = xmlHashLookup(schema->schemasImports, namespace);
    if (import != NULL)
	ret = xmlSchemaGetElem(import->schema, name, namespace, level + 1);
#ifdef DEBUG
    if (ret == NULL) {
        if (namespace == NULL)
            fprintf(stderr, "Unable to lookup type %s", name);
        else
            fprintf(stderr, "Unable to lookup type %s:%s", name,
                    namespace);
    }
#endif
    return (ret);
}

/**
 * xmlSchemaGetType:
 * @schema:  the schemas context
 * @name:  the type name
 * @ns:  the type namespace
 *
 * Lookup a type in the schemas or the predefined types
 *
 * Returns the group definition or NULL if not found.
 */
static xmlSchemaTypePtr
xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
                 const xmlChar * namespace)
{
    xmlSchemaTypePtr ret;
    xmlSchemaImportPtr import;

    if (name == NULL)
        return (NULL);
    if (schema != NULL) {
        ret = xmlHashLookup2(schema->typeDecl, name, namespace);
        if (ret != NULL)
            return (ret);
    }
    ret = xmlSchemaGetPredefinedType(name, namespace);
    if (ret != NULL)
	return (ret);
    import = xmlHashLookup(schema->schemasImports, namespace);
    if (import != NULL)
	ret = xmlSchemaGetType(import->schema, name, namespace);
#ifdef DEBUG
    if (ret == NULL) {
        if (namespace == NULL)
            fprintf(stderr, "Unable to lookup type %s", name);
        else
            fprintf(stderr, "Unable to lookup type %s:%s", name,
                    namespace);
    }
#endif
    return (ret);
}

/************************************************************************
 * 									*
 * 			Parsing functions				*
 * 									*
 ************************************************************************/

#define IS_BLANK_NODE(n)						\
    (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content)))

/**
 * xmlSchemaIsBlank:
 * @str:  a string
 *
 * Check if a string is ignorable
 *
 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
 */
static int
xmlSchemaIsBlank(xmlChar * str)
{
    if (str == NULL)
        return (1);
    while (*str != 0) {
        if (!(IS_BLANK_CH(*str)))
            return (0);
        str++;
    }
    return (1);
}

/**
 * xmlSchemaAddNotation:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @name:  the item name
 *
 * Add an XML schema Attrribute declaration
 * *WARNING* this interface is highly subject to change
 *
 * Returns the new struture or NULL in case of error
 */
static xmlSchemaNotationPtr
xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                     const xmlChar * name)
{
    xmlSchemaNotationPtr ret = NULL;
    int val;

    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
        return (NULL);

    if (schema->notaDecl == NULL)
        schema->notaDecl = xmlHashCreate(10);
    if (schema->notaDecl == NULL)
        return (NULL);

    ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
    if (ret == NULL) {
        xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchemaNotation));
    ret->name = xmlDictLookup(ctxt->dict, name, -1);
    val = xmlHashAddEntry2(schema->notaDecl, name, schema->targetNamespace,
                           ret);
    if (val != 0) {
	xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
		      XML_SCHEMAP_REDEFINED_NOTATION,
                      "Notation %s already defined\n",
                      name, NULL);
        xmlFree(ret);
        return (NULL);
    }
    return (ret);
}


/**
 * xmlSchemaAddAttribute:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @name:  the item name
 * @namespace:  the namespace
 *
 * Add an XML schema Attrribute declaration
 * *WARNING* this interface is highly subject to change
 *
 * Returns the new struture or NULL in case of error
 */
static xmlSchemaAttributePtr
xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                      const xmlChar * name, const xmlChar * namespace)
{
    xmlSchemaAttributePtr ret = NULL;
    int val;

    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
        return (NULL);

#ifdef DEBUG
    fprintf(stderr, "Adding attribute %s\n", name);
    if (namespace != NULL)
	fprintf(stderr, "  target namespace %s\n", namespace);
#endif

    if (schema->attrDecl == NULL)
        schema->attrDecl = xmlHashCreate(10);
    if (schema->attrDecl == NULL)
        return (NULL);

    ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
    if (ret == NULL) {
        xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchemaAttribute));
    ret->name = xmlDictLookup(ctxt->dict, name, -1);
    ret->targetNamespace = xmlDictLookup(ctxt->dict, namespace, -1);
    val = xmlHashAddEntry3(schema->attrDecl, name,
                           schema->targetNamespace, ctxt->container, ret);
    if (val != 0) {
	xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
		      XML_SCHEMAP_REDEFINED_ATTR,
                      "Attribute %s already defined\n",
                      name, NULL);
        xmlFree(ret);
        return (NULL);
    }
    return (ret);
}

/**
 * xmlSchemaAddAttributeGroup:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @name:  the item name
 *
 * Add an XML schema Attrribute Group declaration
 *
 * Returns the new struture or NULL in case of error
 */
static xmlSchemaAttributeGroupPtr
xmlSchemaAddAttributeGroup(xmlSchemaParserCtxtPtr ctxt,
                           xmlSchemaPtr schema, const xmlChar * name)
{
    xmlSchemaAttributeGroupPtr ret = NULL;
    int val;

    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
        return (NULL);

    if (schema->attrgrpDecl == NULL)
        schema->attrgrpDecl = xmlHashCreate(10);
    if (schema->attrgrpDecl == NULL)
        return (NULL);

    ret =
        (xmlSchemaAttributeGroupPtr)
        xmlMalloc(sizeof(xmlSchemaAttributeGroup));
    if (ret == NULL) {
        xmlSchemaPErrMemory(ctxt, "allocating attribute group", NULL);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
    ret->name = xmlDictLookup(ctxt->dict, name, -1);
    val = xmlHashAddEntry3(schema->attrgrpDecl, name,
                           schema->targetNamespace, ctxt->container, ret);
    if (val != 0) {
	xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
		      XML_SCHEMAP_REDEFINED_ATTRGROUP,
                      "Attribute group %s already defined\n",
                      name, NULL);
        xmlFree(ret);
        return (NULL);
    }
    return (ret);
}

/**
 * xmlSchemaAddElement:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @name:  the type name
 * @namespace:  the type namespace
 *
 * Add an XML schema Element declaration
 * *WARNING* this interface is highly subject to change
 *
 * Returns the new struture or NULL in case of error
 */
static xmlSchemaElementPtr
xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                    const xmlChar * name, const xmlChar * namespace)
{
    xmlSchemaElementPtr ret = NULL;
    int val;

    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
        return (NULL);

#ifdef DEBUG
    fprintf(stderr, "Adding element %s\n", name);
    if (namespace != NULL)
	fprintf(stderr, "  target namespace %s\n", namespace);
#endif

    if (schema->elemDecl == NULL)
        schema->elemDecl = xmlHashCreate(10);
    if (schema->elemDecl == NULL)
        return (NULL);

    ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
    if (ret == NULL) {
        xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchemaElement));
    ret->name = xmlDictLookup(ctxt->dict, name, -1);
    ret->targetNamespace = xmlDictLookup(ctxt->dict, namespace, -1);
    val = xmlHashAddEntry3(schema->elemDecl, name,
                           namespace, ctxt->container, ret);
    if (val != 0) {
        char buf[100];

        snprintf(buf, 99, "privatieelem %d", ctxt->counter++ + 1);
        val = xmlHashAddEntry3(schema->elemDecl, name, (xmlChar *) buf,
                               namespace, ret);
        if (val != 0) {
	    xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
			  XML_SCHEMAP_REDEFINED_ELEMENT,
			  "Element %s already defined\n",
			  name, NULL);
            xmlFree(ret);
            return (NULL);
        }
    }
    return (ret);
}

/**
 * xmlSchemaAddType:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @name:  the item name
 * @namespace:  the namespace
 *
 * Add an XML schema Simple Type definition
 * *WARNING* this interface is highly subject to change
 *
 * Returns the new struture or NULL in case of error
 */
static xmlSchemaTypePtr
xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                 const xmlChar * name, const xmlChar * namespace)
{
    xmlSchemaTypePtr ret = NULL;
    int val;

    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
        return (NULL);

#ifdef DEBUG
    fprintf(stderr, "Adding type %s\n", name);
    if (namespace != NULL)
	fprintf(stderr, "  target namespace %s\n", namespace);
#endif

    if (schema->typeDecl == NULL)
        schema->typeDecl = xmlHashCreate(10);
    if (schema->typeDecl == NULL)
        return (NULL);

    ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
    if (ret == NULL) {
        xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchemaType));
    ret->name = xmlDictLookup(ctxt->dict, name, -1);
    ret->redef = NULL;
    val = xmlHashAddEntry2(schema->typeDecl, name, namespace, ret);
    if (val != 0) {
        if (ctxt->includes == 0) {
	    xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
			  XML_SCHEMAP_REDEFINED_TYPE,
			  "Type %s already defined\n",
			  name, NULL);
	    xmlFree(ret);
	    return (NULL);
	} else {
	    xmlSchemaTypePtr prev;

	    prev = xmlHashLookup2(schema->typeDecl, name, namespace);
	    if (prev == NULL) {
		xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
			      XML_ERR_INTERNAL_ERROR,
			      "Internal error on type %s definition\n",
			      name, NULL);
		xmlFree(ret);
		return (NULL);
	    }
	    ret->redef = prev->redef;
	    prev->redef = ret;
	}
    }
    ret->minOccurs = 1;
    ret->maxOccurs = 1;

    return (ret);
}

/**
 * xmlSchemaAddGroup:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @name:  the group name
 *
 * Add an XML schema Group definition
 *
 * Returns the new struture or NULL in case of error
 */
static xmlSchemaTypePtr
xmlSchemaAddGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                  const xmlChar * name)
{
    xmlSchemaTypePtr ret = NULL;
    int val;

    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
        return (NULL);

    if (schema->groupDecl == NULL)
        schema->groupDecl = xmlHashCreate(10);
    if (schema->groupDecl == NULL)
        return (NULL);

    ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
    if (ret == NULL) {
        xmlSchemaPErrMemory(ctxt, "adding group", NULL);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchemaType));
    ret->name = xmlDictLookup(ctxt->dict, name, -1);
    val =
        xmlHashAddEntry2(schema->groupDecl, name, schema->targetNamespace,
                         ret);
    if (val != 0) {
	xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
		      XML_SCHEMAP_REDEFINED_GROUP,
                      "Group %s already defined\n",
                      name, NULL);
        xmlFree(ret);
        return (NULL);
    }
    ret->minOccurs = 1;
    ret->maxOccurs = 1;

    return (ret);
}

/************************************************************************
 * 									*
 *		Utilities for parsing					*
 * 									*
 ************************************************************************/

/**
 * xmlGetQNameProp:
 * @ctxt:  a schema validation context
 * @node:  a subtree containing XML Schema informations
 * @name:  the attribute name
 * @namespace:  the result namespace if any
 *
 * Extract a QName Attribute value
 *
 * Returns the NCName or NULL if not found, and also update @namespace
 *    with the namespace URI
 */
static const xmlChar *
xmlGetQNameProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
                const char *name, const xmlChar ** namespace)
{
    const xmlChar *val;
    xmlNsPtr ns;
    const xmlChar *ret, *prefix;
    int len;

    *namespace = NULL;
    val = xmlSchemaGetProp(ctxt, node, name);
    if (val == NULL)
        return (NULL);

    if (!strchr(val, ':')) {
	ns = xmlSearchNs(node->doc, node, 0);
	if (ns) {
	    *namespace = xmlDictLookup(ctxt->dict, ns->href, -1);
	    return (val);
	}
    }
    ret = xmlSplitQName3(val, &len);
    if (ret == NULL) {
        return (val);
    }
    ret = xmlDictLookup(ctxt->dict, ret, -1);
    prefix = xmlDictLookup(ctxt->dict, val, len);

    ns = xmlSearchNs(node->doc, node, prefix);
    if (ns == NULL) {
        xmlSchemaPErr(ctxt, node, XML_SCHEMAP_PREFIX_UNDEFINED,
                      "Attribute %s: the QName prefix %s is undefined\n",
                      (const xmlChar *) name, prefix);
    } else {
        *namespace = xmlDictLookup(ctxt->dict, ns->href, -1);
    }
    return (ret);
}

/**
 * xmlGetMaxOccurs:
 * @ctxt:  a schema validation context
 * @node:  a subtree containing XML Schema informations
 *
 * Get the maxOccurs property
 *
 * Returns the default if not found, or the value
 */
static int
xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
{
    const xmlChar *val, *cur;
    int ret = 0;

    val = xmlSchemaGetProp(ctxt, node, "maxOccurs");
    if (val == NULL)
        return (1);

    if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
        return (UNBOUNDED);  /* encoding it with -1 might be another option */
    }

    cur = val;
    while (IS_BLANK_CH(*cur))
        cur++;
    while ((*cur >= '0') && (*cur <= '9')) {
        ret = ret * 10 + (*cur - '0');
        cur++;
    }
    while (IS_BLANK_CH(*cur))
        cur++;
    if (*cur != 0) {
        xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_MAXOCCURS,
                      "invalid value for maxOccurs: %s\n", val, NULL);
        return (1);
    }
    return (ret);
}

/**
 * xmlGetMinOccurs:
 * @ctxt:  a schema validation context
 * @node:  a subtree containing XML Schema informations
 *
 * Get the minOccurs property
 *
 * Returns the default if not found, or the value
 */
static int
xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
{
    const xmlChar *val, *cur;
    int ret = 0;

    val = xmlSchemaGetProp(ctxt, node, "minOccurs");
    if (val == NULL)
        return (1);

    cur = val;
    while (IS_BLANK_CH(*cur))
        cur++;
    while ((*cur >= '0') && (*cur <= '9')) {
        ret = ret * 10 + (*cur - '0');
        cur++;
    }
    while (IS_BLANK_CH(*cur))
        cur++;
    if (*cur != 0) {
        xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_MINOCCURS,
                      "invalid value for minOccurs: %s\n", val, NULL);
        return (1);
    }
    return (ret);
}

/**
 * xmlGetBooleanProp:
 * @ctxt:  a schema validation context
 * @node:  a subtree containing XML Schema informations
 * @name:  the attribute name
 * @def:  the default value
 *
 * Get is a bolean property is set
 *
 * Returns the default if not found, 0 if found to be false,
 *         1 if found to be true
 */
static int
xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
                  const char *name, int def)
{
    const xmlChar *val;

    val = xmlSchemaGetProp(ctxt, node, name);
    if (val == NULL)
        return (def);

    if (xmlStrEqual(val, BAD_CAST "true"))
        def = 1;
    else if (xmlStrEqual(val, BAD_CAST "false"))
        def = 0;
    else {
        xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_BOOLEAN,
                      "Attribute %s: the value %s is not boolean\n",
                      (const xmlChar *) name, val);
    }
    return (def);
}

/************************************************************************
 * 									*
 *		Shema extraction from an Infoset			*
 * 									*
 ************************************************************************/
static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
                                                 ctxt, xmlSchemaPtr schema,
                                                 xmlNodePtr node);
static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
                                                  ctxt,
                                                  xmlSchemaPtr schema,
                                                  xmlNodePtr node);
static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
                                                  ctxt,
                                                  xmlSchemaPtr schema,
                                                  xmlNodePtr node,
                                                  int simple);
static xmlSchemaTypePtr xmlSchemaParseSequence(xmlSchemaParserCtxtPtr ctxt,
                                               xmlSchemaPtr schema,
                                               xmlNodePtr node);
static xmlSchemaTypePtr xmlSchemaParseAll(xmlSchemaParserCtxtPtr ctxt,
                                          xmlSchemaPtr schema,
                                          xmlNodePtr node);
static xmlSchemaAttributePtr xmlSchemaParseAttribute(xmlSchemaParserCtxtPtr
                                                     ctxt,
                                                     xmlSchemaPtr schema,
                                                     xmlNodePtr node);
static xmlSchemaAttributeGroupPtr
xmlSchemaParseAttributeGroup(xmlSchemaParserCtxtPtr ctxt,
                             xmlSchemaPtr schema, xmlNodePtr node);
static xmlSchemaTypePtr xmlSchemaParseChoice(xmlSchemaParserCtxtPtr ctxt,
                                             xmlSchemaPtr schema,
                                             xmlNodePtr node);
static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
                                           xmlSchemaPtr schema,
                                           xmlNodePtr node);
static xmlSchemaAttributePtr
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
                           xmlSchemaPtr schema, xmlNodePtr node);

/**
 * xmlSchemaParseAttrDecls:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 * @type:  the hosting type
 *
 * parse a XML schema attrDecls declaration corresponding to
 * <!ENTITY % attrDecls  
 *       '((%attribute;| %attributeGroup;)*,(%anyAttribute;)?)'>
 */
static xmlNodePtr
xmlSchemaParseAttrDecls(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                        xmlNodePtr child, xmlSchemaTypePtr type)
{
    xmlSchemaAttributePtr lastattr, attr;

    lastattr = NULL;
    while ((IS_SCHEMA(child, "attribute")) ||
           (IS_SCHEMA(child, "attributeGroup"))) {
        attr = NULL;
        if (IS_SCHEMA(child, "attribute")) {
            attr = xmlSchemaParseAttribute(ctxt, schema, child);
        } else if (IS_SCHEMA(child, "attributeGroup")) {
            attr = (xmlSchemaAttributePtr)
                xmlSchemaParseAttributeGroup(ctxt, schema, child);
        }
        if (attr != NULL) {
            if (lastattr == NULL) {
                type->attributes = attr;
                lastattr = attr;
            } else {
                lastattr->next = attr;
                lastattr = attr;
            }
        }
        child = child->next;
    }
    if (IS_SCHEMA(child, "anyAttribute")) {
        attr = xmlSchemaParseAnyAttribute(ctxt, schema, child);
        if (attr != NULL) {
            if (lastattr == NULL) {
                type->attributes = attr;
                lastattr = attr;
            } else {
                lastattr->next = attr;
                lastattr = attr;
            }
        }
        child = child->next;
    }
    return (child);
}

/**
 * xmlSchemaParseAnnotation:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema Attrribute declaration
 * *WARNING* this interface is highly subject to change
 *
 * Returns -1 in case of error, 0 if the declaration is inproper and
 *         1 in case of success.
 */
static xmlSchemaAnnotPtr
xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                         xmlNodePtr node)
{
    xmlSchemaAnnotPtr ret;

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
        return (NULL);
    ret = xmlSchemaNewAnnot(ctxt, node);

    return (ret);
}

/**
 * xmlSchemaParseFacet:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema Facet declaration
 * *WARNING* this interface is highly subject to change
 *
 * Returns the new type structure or NULL in case of error
 */
static xmlSchemaFacetPtr
xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                    xmlNodePtr node)
{
    xmlSchemaFacetPtr facet;
    xmlNodePtr child = NULL;
    const xmlChar *value;

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
        return (NULL);

    facet = xmlSchemaNewFacet();
    if (facet == NULL) {
        xmlSchemaPErrMemory(ctxt, "allocating facet", node);
        return (NULL);
    }
    facet->node = node;
    value = xmlSchemaGetProp(ctxt, node, "value");
    if (value == NULL) {
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
                       "Facet %s has no value\n", node->name, NULL);
        xmlSchemaFreeFacet(facet);
        return (NULL);
    }
    if (IS_SCHEMA(node, "minInclusive")) {
        facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
    } else if (IS_SCHEMA(node, "minExclusive")) {
        facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
    } else if (IS_SCHEMA(node, "maxInclusive")) {
        facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
    } else if (IS_SCHEMA(node, "maxExclusive")) {
        facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
    } else if (IS_SCHEMA(node, "totalDigits")) {
        facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
    } else if (IS_SCHEMA(node, "fractionDigits")) {
        facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
    } else if (IS_SCHEMA(node, "pattern")) {
        facet->type = XML_SCHEMA_FACET_PATTERN;
    } else if (IS_SCHEMA(node, "enumeration")) {
        facet->type = XML_SCHEMA_FACET_ENUMERATION;
    } else if (IS_SCHEMA(node, "whiteSpace")) {
        facet->type = XML_SCHEMA_FACET_WHITESPACE;
    } else if (IS_SCHEMA(node, "length")) {
        facet->type = XML_SCHEMA_FACET_LENGTH;
    } else if (IS_SCHEMA(node, "maxLength")) {
        facet->type = XML_SCHEMA_FACET_MAXLENGTH;
    } else if (IS_SCHEMA(node, "minLength")) {
        facet->type = XML_SCHEMA_FACET_MINLENGTH;
    } else {
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
                       "Unknown facet type %s\n", node->name, NULL);
        xmlSchemaFreeFacet(facet);
        return (NULL);
    }
    facet->id = xmlSchemaGetProp(ctxt, node, "id");
    facet->value = value;
    child = node->children;

    if (IS_SCHEMA(child, "annotation")) {
        facet->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
        child = child->next;
    }
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
                       "Facet %s has unexpected child content\n",
                       node->name, NULL);
    }
    return (facet);
}

/**
 * xmlSchemaParseAny:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema Any declaration
 * *WARNING* this interface is highly subject to change
 *
 * Returns the new type structure or NULL in case of error
 */
static xmlSchemaTypePtr
xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                  xmlNodePtr node)
{
    xmlSchemaTypePtr type;
    xmlNodePtr child = NULL;
    xmlChar name[30];

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
        return (NULL);
    snprintf((char *) name, 30, "any %d", ctxt->counter++ + 1);
    type = xmlSchemaAddType(ctxt, schema, name, NULL);
    if (type == NULL)
        return (NULL);
    type->node = node;
    type->type = XML_SCHEMA_TYPE_ANY;
    child = node->children;
    type->minOccurs = xmlGetMinOccurs(ctxt, node);
    type->maxOccurs = xmlGetMaxOccurs(ctxt, node);

    if (IS_SCHEMA(child, "annotation")) {
        type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
        child = child->next;
    }
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child,
                       XML_SCHEMAP_UNKNOWN_SEQUENCE_CHILD,
                       "Sequence %s has unexpected content\n", type->name,
                       NULL);
    }

    return (type);
}

/**
 * xmlSchemaParseNotation:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema Notation declaration
 *
 * Returns the new structure or NULL in case of error
 */
static xmlSchemaNotationPtr
xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                       xmlNodePtr node)
{
    const xmlChar *name;
    xmlSchemaNotationPtr ret;
    xmlNodePtr child = NULL;

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
        return (NULL);
    name = xmlSchemaGetProp(ctxt, node, "name");
    if (name == NULL) {
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
                       "Notation has no name\n", NULL, NULL);
        return (NULL);
    }
    ret = xmlSchemaAddNotation(ctxt, schema, name);
    if (ret == NULL) {
        return (NULL);
    }
    child = node->children;
    if (IS_SCHEMA(child, "annotation")) {
        ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
        child = child->next;
    }
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child,
                       XML_SCHEMAP_UNKNOWN_NOTATION_CHILD,
                       "notation %s has unexpected content\n", name, NULL);
    }

    return (ret);
}

/**
 * xmlSchemaParseAnyAttribute:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema AnyAttrribute declaration
 * *WARNING* this interface is highly subject to change
 *
 * Returns an attribute def structure or NULL
 */
static xmlSchemaAttributePtr
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
                           xmlSchemaPtr schema, xmlNodePtr node)
{
    const xmlChar *processContents;
    xmlSchemaAttributePtr ret;
    xmlNodePtr child = NULL;
    char name[100];
    const xmlChar *local, *ns;


    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
        return (NULL);

    snprintf(name, 99, "anyattr %d", ctxt->counter++ + 1);
    local = xmlSchemaGetNamespace(ctxt, schema, node, BAD_CAST "anyattr", &ns);
    ret = xmlSchemaAddAttribute(ctxt, schema, BAD_CAST name, ns);
    if (ret == NULL) {
        return (NULL);
    }
    ret->id = xmlSchemaGetProp(ctxt, node, "id");
    processContents = xmlSchemaGetProp(ctxt, node, "processContents");
    if ((processContents == NULL)
        || (xmlStrEqual(processContents, (const xmlChar *) "strict"))) {
        ret->occurs = XML_SCHEMAS_ANYATTR_STRICT;
    } else if (xmlStrEqual(processContents, (const xmlChar *) "skip")) {
        ret->occurs = XML_SCHEMAS_ANYATTR_SKIP;
    } else if (xmlStrEqual(processContents, (const xmlChar *) "lax")) {
        ret->occurs = XML_SCHEMAS_ANYATTR_LAX;
    } else {
        xmlSchemaPErr2(ctxt, node, child,
                       XML_SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD,
                       "anyAttribute has unexpected content for processContents: %s\n",
                       processContents, NULL);
        ret->occurs = XML_SCHEMAS_ANYATTR_STRICT;
    }

    child = node->children;
    if (IS_SCHEMA(child, "annotation")) {
        ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
        child = child->next;
    }
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child,
                       XML_SCHEMAP_UNKNOWN_ANYATTRIBUTE_CHILD,
                       "anyAttribute %s has unexpected content\n",
                       (const xmlChar *) name, NULL);
    }

    return (ret);
}


/**
 * xmlSchemaParseAttribute:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema Attrribute declaration
 * *WARNING* this interface is highly subject to change
 *
 * Returns -1 in case of error, 0 if the declaration is inproper and
 *         1 in case of success.
 */
static xmlSchemaAttributePtr
xmlSchemaParseAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                        xmlNodePtr node)
{
    const xmlChar *name, *refNs = NULL, *ref = NULL;
    xmlSchemaAttributePtr ret;
    xmlNodePtr child = NULL;
    char buf[100];

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
        return (NULL);
    name = xmlSchemaGetProp(ctxt, node, "name");
    if (name == NULL) {

        ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
        if (ref == NULL) {
            xmlSchemaPErr2(ctxt, node, child,
                           XML_SCHEMAP_ATTR_NONAME_NOREF,
                           "Attribute has no name nor ref\n", NULL, NULL);
            return (NULL);
        }
        snprintf(buf, 99, "anonattr %d", ctxt->counter++ + 1);
        name = (const xmlChar *) buf;
	ret = xmlSchemaAddAttribute(ctxt, schema, name, NULL);
    } else {
        const xmlChar *local, *ns;

        local = xmlSchemaGetNamespace(ctxt, schema, node, name, &ns);
	ret = xmlSchemaAddAttribute(ctxt, schema, local, ns);
    }
    if (ret == NULL) {
        return (NULL);
    }
    ret->ref = ref;
    ret->refNs = refNs;
    if ((ret->targetNamespace != NULL) &&
        ((schema->flags & XML_SCHEMAS_QUALIF_ATTR) == 0) &&
	(xmlStrEqual(ret->targetNamespace, schema->targetNamespace)))
	ret->flags |= XML_SCHEMAS_ATTR_NSDEFAULT;
    ret->typeName = xmlGetQNameProp(ctxt, node, "type", &(ret->typeNs));
    ret->node = node;
    child = node->children;
    if (IS_SCHEMA(child, "annotation")) {
        ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
        child = child->next;
    }
    if (IS_SCHEMA(child, "simpleType")) {
        ret->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child);
        child = child->next;
    }
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_ATTR_CHILD,
                       "attribute %s has unexpected content\n", name,
                       NULL);
    }

    return (ret);
}

/**
 * xmlSchemaParseAttributeGroup:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema Attribute Group declaration
 * *WARNING* this interface is highly subject to change
 *
 * Returns the attribute group or NULL in case of error.
 */
static xmlSchemaAttributeGroupPtr
xmlSchemaParseAttributeGroup(xmlSchemaParserCtxtPtr ctxt,
                             xmlSchemaPtr schema, xmlNodePtr node)
{
    const xmlChar *name, *refNs = NULL, *ref = NULL;
    xmlSchemaAttributeGroupPtr ret;
    xmlSchemaAttributePtr last = NULL, attr;
    xmlNodePtr child = NULL;
    const xmlChar *oldcontainer;
    char buf[100];

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
        return (NULL);
    oldcontainer = ctxt->container;
    name = xmlSchemaGetProp(ctxt, node, "name");
    if (name == NULL) {

        ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
        if (ref == NULL) {
            xmlSchemaPErr2(ctxt, node, child,
                           XML_SCHEMAP_ATTRGRP_NONAME_NOREF,
                           "AttributeGroup has no name nor ref\n", NULL,
                           NULL);
            return (NULL);
        }
        snprintf(buf, 99, "anonattrgroup %d", ctxt->counter++ + 1);
        name = (const xmlChar *) buf;
        if (name == NULL) {
	    xmlSchemaPErrMemory(ctxt, "creating attribute group", node);
            return (NULL);
        }
    }
    ret = xmlSchemaAddAttributeGroup(ctxt, schema, name);
    if (ret == NULL) {
        return (NULL);
    }
    ret->ref = ref;
    ret->refNs = refNs;
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
    ret->node = node;
    child = node->children;
    ctxt->container = name;
    if (IS_SCHEMA(child, "annotation")) {
        ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
        child = child->next;
    }
    while ((IS_SCHEMA(child, "attribute")) ||
           (IS_SCHEMA(child, "attributeGroup"))) {
        attr = NULL;
        if (IS_SCHEMA(child, "attribute")) {
            attr = xmlSchemaParseAttribute(ctxt, schema, child);
        } else if (IS_SCHEMA(child, "attributeGroup")) {
            attr = (xmlSchemaAttributePtr)
                xmlSchemaParseAttributeGroup(ctxt, schema, child);
        }
        if (attr != NULL) {
            if (last == NULL) {
                ret->attributes = attr;
                last = attr;
            } else {
                last->next = attr;
                last = attr;
            }
        }
        child = child->next;
    }
    if (IS_SCHEMA(child, "anyAttribute")) {
        TODO
	child = child->next;
    }
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child,
                       XML_SCHEMAP_UNKNOWN_ATTRGRP_CHILD,
                       "attribute group %s has unexpected content\n", name,
                       NULL);
    }
    ctxt->container = oldcontainer;
    return (ret);
}

/**
 * xmlSchemaParseElement:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema Element declaration
 * *WARNING* this interface is highly subject to change
 *
 * Returns -1 in case of error, 0 if the declaration is inproper and
 *         1 in case of success.
 */
static xmlSchemaElementPtr
xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                      xmlNodePtr node, int toplevel)
{
    const xmlChar *name, *fixed;
    const xmlChar *refNs = NULL, *ref = NULL;
    xmlSchemaElementPtr ret;
    xmlNodePtr child = NULL;
    const xmlChar *oldcontainer;
    char buf[100];

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
        return (NULL);
    oldcontainer = ctxt->container;
    name = xmlSchemaGetProp(ctxt, node, "name");
    if (name == NULL) {

        ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
        if (ref == NULL) {
            xmlSchemaPErr2(ctxt, node, child,
                           XML_SCHEMAP_ELEM_NONAME_NOREF,
                           "Element has no name nor ref\n", NULL, NULL);
            return (NULL);
        }
        snprintf(buf, 99, "anonelem %d", ctxt->counter++ + 1);
        name = (const xmlChar *) buf;
	ret = xmlSchemaAddElement(ctxt, schema, name, NULL);
    } else {
        const xmlChar *local, *ns;

        local = xmlSchemaGetNamespace(ctxt, schema, node, name, &ns);
	ret = xmlSchemaAddElement(ctxt, schema, local, ns);
    }
    if (ret != NULL)
	ret->node = node;
    if (ret == NULL) {
        return (NULL);
    }
    ret->type = XML_SCHEMA_TYPE_ELEMENT;
    ret->ref = ref;
    ret->refNs = refNs;
    if (ref != NULL)
        ret->flags |= XML_SCHEMAS_ELEM_REF;
    if (toplevel)
        ret->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
    if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
        ret->flags |= XML_SCHEMAS_ELEM_NILLABLE;
    if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
        ret->flags |= XML_SCHEMAS_ELEM_NILLABLE;
    ctxt->container = name;

    ret->id = xmlSchemaGetProp(ctxt, node, "id");
    ret->namedType =
        xmlGetQNameProp(ctxt, node, "type", &(ret->namedTypeNs));
    ret->substGroup =
        xmlGetQNameProp(ctxt, node, "substitutionGroup",
                        &(ret->substGroupNs));
    fixed = xmlSchemaGetProp(ctxt, node, "fixed");
    ret->minOccurs = xmlGetMinOccurs(ctxt, node);
    ret->maxOccurs = xmlGetMaxOccurs(ctxt, node);

    ret->value = xmlSchemaGetProp(ctxt, node, "default");
    if ((ret->value != NULL) && (fixed != NULL)) {
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_ELEM_DEFAULT_FIXED,
                       "Element %s has both default and fixed\n",
		       ret->name, NULL);
    } else if (fixed != NULL) {
        ret->flags |= XML_SCHEMAS_ELEM_FIXED;
        ret->value = fixed;
    }

    child = node->children;
    if (IS_SCHEMA(child, "annotation")) {
        ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
        child = child->next;
    }
    if (IS_SCHEMA(child, "complexType")) {
        ret->subtypes = xmlSchemaParseComplexType(ctxt, schema, child);
        child = child->next;
    } else if (IS_SCHEMA(child, "simpleType")) {
        ret->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child);
        child = child->next;
    }
    while ((IS_SCHEMA(child, "unique")) ||
           (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
        TODO child = child->next;
    }
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_ELEM_CHILD,
                       "element %s has unexpected content\n", name, NULL);
    }

    ctxt->container = oldcontainer;
    return (ret);
}

/**
 * xmlSchemaParseUnion:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema Union definition
 * *WARNING* this interface is highly subject to change
 *
 * Returns -1 in case of error, 0 if the declaration is inproper and
 *         1 in case of success.
 */
static xmlSchemaTypePtr
xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                    xmlNodePtr node)
{
    xmlSchemaTypePtr type, subtype, last = NULL;
    xmlNodePtr child = NULL;
    xmlChar name[30];

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
        return (NULL);


    snprintf((char *) name, 30, "union %d", ctxt->counter++ + 1);
    type = xmlSchemaAddType(ctxt, schema, name, NULL);
    if (type == NULL)
        return (NULL);
    type->node = node;
    type->type = XML_SCHEMA_TYPE_LIST;
    type->id = xmlSchemaGetProp(ctxt, node, "id");
    type->ref = xmlSchemaGetProp(ctxt, node, "memberTypes");

    child = node->children;
    if (IS_SCHEMA(child, "annotation")) {
        type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
        child = child->next;
    }
    while (IS_SCHEMA(child, "simpleType")) {
        subtype = (xmlSchemaTypePtr)
            xmlSchemaParseSimpleType(ctxt, schema, child);
        if (subtype != NULL) {
            if (last == NULL) {
                type->subtypes = subtype;
                last = subtype;
            } else {
                last->next = subtype;
                last = subtype;
            }
            last->next = NULL;
        }
        child = child->next;
    }
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_UNION_CHILD,
                       "Union %s has unexpected content\n", type->name,
                       NULL);
    }
    return (type);
}

/**
 * xmlSchemaParseList:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema List definition
 * *WARNING* this interface is highly subject to change
 *
 * Returns -1 in case of error, 0 if the declaration is inproper and
 *         1 in case of success.
 */
static xmlSchemaTypePtr
xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                   xmlNodePtr node)
{
    xmlSchemaTypePtr type, subtype;
    xmlNodePtr child = NULL;
    xmlChar name[30];

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
        return (NULL);

    snprintf((char *) name, 30, "list %d", ctxt->counter++ + 1);
    type = xmlSchemaAddType(ctxt, schema, name, NULL);
    if (type == NULL)
        return (NULL);
    type->node = node;
    type->type = XML_SCHEMA_TYPE_LIST;
    type->id = xmlSchemaGetProp(ctxt, node, "id");
    type->ref = xmlGetQNameProp(ctxt, node, "ref", &(type->refNs));

    child = node->children;
    if (IS_SCHEMA(child, "annotation")) {
        type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
        child = child->next;
    }
    subtype = NULL;
    if (IS_SCHEMA(child, "simpleType")) {
        subtype = (xmlSchemaTypePtr)
            xmlSchemaParseSimpleType(ctxt, schema, child);
        child = child->next;
        type->subtypes = subtype;
    }
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_LIST_CHILD,
                       "List %s has unexpected content\n", type->name,
                       NULL);
    }
    return (type);
}

/**
 * xmlSchemaParseSimpleType:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema Simple Type definition
 * *WARNING* this interface is highly subject to change
 *
 * Returns -1 in case of error, 0 if the declaration is inproper and
 *         1 in case of success.
 */
static xmlSchemaTypePtr
xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                         xmlNodePtr node)
{
    xmlSchemaTypePtr type, subtype;
    xmlNodePtr child = NULL;
    const xmlChar *name;

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
        return (NULL);


    name = xmlSchemaGetProp(ctxt, node, "name");
    if (name == NULL) {
        char buf[100];

        snprintf(buf, 99, "simpletype %d", ctxt->counter++ + 1);
	type = xmlSchemaAddType(ctxt, schema, (const xmlChar *)buf, NULL);
    } else {
	const xmlChar *local, *ns;

        local = xmlSchemaGetNamespace(ctxt, schema, node, name, &ns);
	type = xmlSchemaAddType(ctxt, schema, local, ns);
    }
    if (type == NULL)
        return (NULL);
    type->node = node;
    type->type = XML_SCHEMA_TYPE_SIMPLE;
    type->id = xmlSchemaGetProp(ctxt, node, "id");

    child = node->children;
    if (IS_SCHEMA(child, "annotation")) {
        type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
        child = child->next;
    }
    subtype = NULL;
    if (IS_SCHEMA(child, "restriction")) {
        subtype = (xmlSchemaTypePtr)
            xmlSchemaParseRestriction(ctxt, schema, child, 1);
        child = child->next;
    } else if (IS_SCHEMA(child, "list")) {
        subtype = (xmlSchemaTypePtr)
            xmlSchemaParseList(ctxt, schema, child);
        child = child->next;
    } else if (IS_SCHEMA(child, "union")) {
        subtype = (xmlSchemaTypePtr)
            xmlSchemaParseUnion(ctxt, schema, child);
        child = child->next;
    }
    type->subtypes = subtype;
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child,
                       XML_SCHEMAP_UNKNOWN_SIMPLETYPE_CHILD,
                       "SimpleType %s has unexpected content\n",
                       type->name, NULL);
    }

    return (type);
}


/**
 * xmlSchemaParseGroup:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema Group definition
 * *WARNING* this interface is highly subject to change
 *
 * Returns -1 in case of error, 0 if the declaration is inproper and
 *         1 in case of success.
 */
static xmlSchemaTypePtr
xmlSchemaParseGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                    xmlNodePtr node)
{
    xmlSchemaTypePtr type, subtype;
    xmlNodePtr child = NULL;
    const xmlChar *name;
    const xmlChar *ref = NULL, *refNs = NULL;
    char buf[100];

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
        return (NULL);


    name = xmlSchemaGetProp(ctxt, node, "name");
    if (name == NULL) {

        ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
        if (ref == NULL) {
            xmlSchemaPErr2(ctxt, node, child,
                           XML_SCHEMAP_GROUP_NONAME_NOREF,
                           "Group has no name nor ref\n", NULL, NULL);
            return (NULL);
        }
	if (refNs == NULL)
	    refNs = schema->targetNamespace;
        snprintf(buf, 99, "anongroup %d", ctxt->counter++ + 1);
        name = (const xmlChar *) buf;
    }
    type = xmlSchemaAddGroup(ctxt, schema, name);
    if (type == NULL)
        return (NULL);

    type->node = node;
    type->type = XML_SCHEMA_TYPE_GROUP;
    type->id = xmlSchemaGetProp(ctxt, node, "id");
    type->ref = ref;
    type->refNs = refNs;
    type->minOccurs = xmlGetMinOccurs(ctxt, node);
    type->maxOccurs = xmlGetMaxOccurs(ctxt, node);

    child = node->children;
    if (IS_SCHEMA(child, "annotation")) {
        type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
        child = child->next;
    }
    subtype = NULL;
    if (IS_SCHEMA(child, "all")) {
        subtype = (xmlSchemaTypePtr)
            xmlSchemaParseAll(ctxt, schema, child);
        child = child->next;
    } else if (IS_SCHEMA(child, "choice")) {
        subtype = xmlSchemaParseChoice(ctxt, schema, child);
        child = child->next;
    } else if (IS_SCHEMA(child, "sequence")) {
        subtype = (xmlSchemaTypePtr)
            xmlSchemaParseSequence(ctxt, schema, child);
        child = child->next;
    }
    if (subtype != NULL)
        type->subtypes = subtype;
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_GROUP_CHILD,
                       "Group %s has unexpected content\n", type->name,
                       NULL);
    }

    return (type);
}

/**
 * xmlSchemaParseAll:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema All definition
 * *WARNING* this interface is highly subject to change
 *
 * Returns -1 in case of error, 0 if the declaration is inproper and
 *         1 in case of success.
 */
static xmlSchemaTypePtr
xmlSchemaParseAll(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                  xmlNodePtr node)
{
    xmlSchemaTypePtr type, subtype, last = NULL;
    xmlNodePtr child = NULL;
    xmlChar name[30];

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
        return (NULL);


    snprintf((char *) name, 30, "all%d", ctxt->counter++ + 1);
    type = xmlSchemaAddType(ctxt, schema, name, NULL);
    if (type == NULL)
        return (NULL);
    type->node = node;
    type->type = XML_SCHEMA_TYPE_ALL;
    type->id = xmlSchemaGetProp(ctxt, node, "id");
    type->minOccurs = xmlGetMinOccurs(ctxt, node);
    if (type->minOccurs > 1)
        xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_MINOCCURS,
	    "invalid value for minOccurs (must be 0 or 1)\n", NULL, NULL);
    type->maxOccurs = xmlGetMaxOccurs(ctxt, node);
    if (type->maxOccurs > 1)
        xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_MAXOCCURS,
	    "invalid value for maxOccurs (must be 0 or 1)\n", NULL, NULL);

    child = node->children;
    if (IS_SCHEMA(child, "annotation")) {
        type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
        child = child->next;
    }
    while (IS_SCHEMA(child, "element")) {
        subtype = (xmlSchemaTypePtr)
            xmlSchemaParseElement(ctxt, schema, child, 0);
        if (subtype != NULL) {
	    if (subtype->minOccurs > 1)
                xmlSchemaPErr(ctxt, child, XML_SCHEMAP_INVALID_MINOCCURS,
	             "invalid value for minOccurs (must be 0 or 1)\n",
		     NULL, NULL);
	    if (subtype->maxOccurs > 1)
	        xmlSchemaPErr(ctxt, child, XML_SCHEMAP_INVALID_MAXOCCURS,
	             "invalid value for maxOccurs (must be 0 or 1)\n",
		     NULL, NULL);
            if (last == NULL) {
                type->subtypes = subtype;
                last = subtype;
            } else {
                last->next = subtype;
                last = subtype;
            }
            last->next = NULL;
        }
        child = child->next;
    }
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_ALL_CHILD,
                       "All %s has unexpected content\n", type->name,
                       NULL);
    }

    return (type);
}

/**
 * xmlSchemaImportSchema
 * 
 * @ctxt:  a schema validation context
 * @schemaLocation:  an URI defining where to find the imported schema
 *
 * import a XML schema
 * *WARNING* this interface is highly subject to change
 *
 * Returns -1 in case of error and 1 in case of success.
 */
static xmlSchemaImportPtr
xmlSchemaImportSchema(xmlSchemaParserCtxtPtr ctxt,
                      const xmlChar *schemaLocation)
{
    xmlSchemaImportPtr import;
    xmlSchemaParserCtxtPtr newctxt;

    newctxt = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
    if (newctxt == NULL) {
        xmlSchemaPErrMemory(ctxt, "allocating schama parser context",
                            NULL);
        return (NULL);
    }
    memset(newctxt, 0, sizeof(xmlSchemaParserCtxt));
    /* Keep the same dictionnary for parsing, really */
    xmlDictReference(ctxt->dict);
    newctxt->dict = ctxt->dict;
    newctxt->includes = 0;
    newctxt->URL = xmlDictLookup(newctxt->dict, schemaLocation, -1);

    xmlSchemaSetParserErrors(newctxt, ctxt->error, ctxt->warning,
	                     ctxt->userData);

    import = (xmlSchemaImport*) xmlMalloc(sizeof(xmlSchemaImport));
    if (import == NULL) {
        xmlSchemaPErrMemory(NULL, "allocating imported schema",
                            NULL);
	xmlSchemaFreeParserCtxt(newctxt);
        return (NULL);
    }

    memset(import, 0, sizeof(xmlSchemaImport));
    import->schemaLocation = xmlDictLookup(ctxt->dict, schemaLocation, -1);
    import->schema = xmlSchemaParse(newctxt);

    if (import->schema == NULL) {
        /* FIXME use another error enum here ? */
        xmlSchemaPErr(ctxt, NULL, XML_SCHEMAS_ERR_INTERNAL,
	              "failed to import schema at location %s\n",
		      schemaLocation, NULL);

	xmlSchemaFreeParserCtxt(newctxt);
	if (import->schemaLocation != NULL)
	    xmlFree((xmlChar *)import->schemaLocation);
	xmlFree(import);
	return NULL;
    }

    xmlSchemaFreeParserCtxt(newctxt);
    return import;
}


/**
 * xmlSchemaParseImport:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema Import definition
 * *WARNING* this interface is highly subject to change
 *
 * Returns -1 in case of error, 0 if the declaration is inproper and
 *         1 in case of success.
 */
static int
xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                     xmlNodePtr node)
{
    xmlNodePtr child = NULL;
    xmlSchemaImportPtr import = NULL;
    const xmlChar *namespace;
    const xmlChar *schemaLocation;
    const xmlChar *previous;
    xmlURIPtr check;


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

    namespace = xmlSchemaGetProp(ctxt, node, "namespace");
    if (namespace != NULL) {
        check = xmlParseURI((const char *) namespace);
        if (check == NULL) {
            xmlSchemaPErr2(ctxt, node, child,
                           XML_SCHEMAP_IMPORT_NAMESPACE_NOT_URI,
                           "Import namespace attribute is not an URI: %s\n",
                           namespace, NULL);
            return (-1);
        } else {
            xmlFreeURI(check);
        }
    }
    schemaLocation = xmlSchemaGetProp(ctxt, node, "schemaLocation");
    if (schemaLocation != NULL) {
        xmlChar *base = NULL;
        xmlChar *URI = NULL;
        check = xmlParseURI((const char *) schemaLocation);
        if (check == NULL) {
            xmlSchemaPErr2(ctxt, node, child,
                           XML_SCHEMAP_IMPORT_SCHEMA_NOT_URI,
                           "Import schemaLocation attribute is not an URI: %s\n",
                           schemaLocation, NULL);
            return (-1);
        } else {
            xmlFreeURI(check);
        }
	base = xmlNodeGetBase(node->doc, node);
	if (base == NULL) {
	    URI = xmlBuildURI(schemaLocation, node->doc->URL);
	} else {
	    URI = xmlBuildURI(schemaLocation, base);
	    xmlFree(base);
	}
	if (URI != NULL) {
	    schemaLocation = xmlDictLookup(ctxt->dict, URI, -1);
	    xmlFree(URI);
	}
    }
    if (schema->schemasImports == NULL) {
        schema->schemasImports = xmlHashCreate(10);
        if (schema->schemasImports == NULL) {
            xmlSchemaPErr2(ctxt, node, child,
                           XML_SCHEMAP_FAILED_BUILD_IMPORT,
                           "Internal: failed to build import table\n",
                           NULL, NULL);
            return (-1);
        }
    }
    if (namespace == NULL) {
        import = xmlHashLookup(schema->schemasImports,
	                               XML_SCHEMAS_DEFAULT_NAMESPACE);
	if (import != NULL)
            previous = import->schemaLocation;
	else
	    previous = NULL;

        if (schemaLocation != NULL) {
            if (previous != NULL) {
                if (!xmlStrEqual(schemaLocation, previous)) {
                    xmlSchemaPErr2(ctxt, node, child,
                                   XML_SCHEMAP_IMPORT_REDEFINE_NSNAME,
                                   "Redefining import for default namespace with a different URI: %s\n",
                                   schemaLocation, NULL);
                }
            } else {
	        import = xmlSchemaImportSchema(ctxt, schemaLocation);
		if (import == NULL) {
		    return (-1);
		}
                xmlHashAddEntry(schema->schemasImports,
                                XML_SCHEMAS_DEFAULT_NAMESPACE,
                                import);
            }
        }
    } else {
        import = xmlHashLookup(schema->schemasImports, namespace);
	if (import != NULL)
	    previous = import->schemaLocation;
	else
	    previous = NULL;

        if (schemaLocation != NULL) {
            if (previous != NULL) {
                if (!xmlStrEqual(schemaLocation, previous)) {
                    xmlSchemaPErr2(ctxt, node, child,
                                   XML_SCHEMAP_IMPORT_REDEFINE_NSNAME,
                                   "Redefining import for namespace %s with a different URI: %s\n",
                                   namespace, schemaLocation);
                }
            } else {
	        import = xmlSchemaImportSchema(ctxt, schemaLocation);
		if (import == NULL) {
		    return (-1);
		}
                xmlHashAddEntry(schema->schemasImports,
                                namespace, import);
            }
        }
    }

    child = node->children;
    while (IS_SCHEMA(child, "annotation")) {
        /*
         * the annotations here are simply discarded ...
         */
        child = child->next;
    }
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_IMPORT_CHILD,
                       "Import has unexpected content\n", NULL, NULL);
        return (-1);
    }
    return (1);
}

/**
 * xmlSchemaCleanupDoc:
 * @ctxt:  a schema validation context
 * @node:  the root of the document.
 *
 * removes unwanted nodes in a schemas document tree
 */
static void
xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
{
    xmlNodePtr delete, cur;

    if ((ctxt == NULL) || (root == NULL)) return;

    /*
     * Remove all the blank text nodes
     */
    delete = NULL;
    cur = root;
    while (cur != NULL) {
        if (delete != NULL) {
            xmlUnlinkNode(delete);
            xmlFreeNode(delete);
            delete = NULL;
        }
        if (cur->type == XML_TEXT_NODE) {
            if (IS_BLANK_NODE(cur)) {
                if (xmlNodeGetSpacePreserve(cur) != 1) {
                    delete = cur;
                }
            }
        } else if ((cur->type != XML_ELEMENT_NODE) &&
                   (cur->type != XML_CDATA_SECTION_NODE)) {
            delete = cur;
            goto skip_children;
        }

        /*
         * Skip to next node
         */
        if (cur->children != NULL) {
            if ((cur->children->type != XML_ENTITY_DECL) &&
                (cur->children->type != XML_ENTITY_REF_NODE) &&
                (cur->children->type != XML_ENTITY_NODE)) {
                cur = cur->children;
                continue;
            }
        }
      skip_children:
        if (cur->next != NULL) {
            cur = cur->next;
            continue;
        }

        do {
            cur = cur->parent;
            if (cur == NULL)
                break;
            if (cur == root) {
                cur = NULL;
                break;
            }
            if (cur->next != NULL) {
                cur = cur->next;
                break;
            }
        } while (cur != NULL);
    }
    if (delete != NULL) {
        xmlUnlinkNode(delete);
        xmlFreeNode(delete);
        delete = NULL;
    }
}

/**
 * xmlSchemaParseSchemaTopLevel:
 * @ctxt:  a schema validation context
 * @schema:  the schemas
 * @nodes:  the list of top level nodes
 *
 * Returns the internal XML Schema structure built from the resource or
 *         NULL in case of error
 */
static void
xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
                             xmlSchemaPtr schema, xmlNodePtr nodes)
{
    xmlNodePtr child;
    xmlSchemaAnnotPtr annot;

    if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
        return;

    child = nodes;
    while ((IS_SCHEMA(child, "include")) ||
	   (IS_SCHEMA(child, "import")) ||
	   (IS_SCHEMA(child, "redefine")) ||
	   (IS_SCHEMA(child, "annotation"))) {
	if (IS_SCHEMA(child, "annotation")) {
	    annot = xmlSchemaParseAnnotation(ctxt, schema, child);
	    if (schema->annot == NULL)
		schema->annot = annot;
	    else
		xmlSchemaFreeAnnot(annot);
	} else if (IS_SCHEMA(child, "import")) {
	    xmlSchemaParseImport(ctxt, schema, child);
	} else if (IS_SCHEMA(child, "include")) {
	    ctxt->includes++;
	    xmlSchemaParseInclude(ctxt, schema, child);
	    ctxt->includes--;
	} else if (IS_SCHEMA(child, "redefine")) {
	    TODO
	}
	child = child->next;
    }
    while (child != NULL) {
	if (IS_SCHEMA(child, "complexType")) {
	    xmlSchemaParseComplexType(ctxt, schema, child);
	    child = child->next;
	} else if (IS_SCHEMA(child, "simpleType")) {
	    xmlSchemaParseSimpleType(ctxt, schema, child);
	    child = child->next;
	} else if (IS_SCHEMA(child, "element")) {
	    xmlSchemaParseElement(ctxt, schema, child, 1);
	    child = child->next;
	} else if (IS_SCHEMA(child, "attribute")) {
	    xmlSchemaParseAttribute(ctxt, schema, child);
	    child = child->next;
	} else if (IS_SCHEMA(child, "attributeGroup")) {
	    xmlSchemaParseAttributeGroup(ctxt, schema, child);
	    child = child->next;
	} else if (IS_SCHEMA(child, "group")) {
	    xmlSchemaParseGroup(ctxt, schema, child);
	    child = child->next;
	} else if (IS_SCHEMA(child, "notation")) {
	    xmlSchemaParseNotation(ctxt, schema, child);
	    child = child->next;
	} else {
	    xmlSchemaPErr2(ctxt, NULL, child,
			   XML_SCHEMAP_UNKNOWN_SCHEMAS_CHILD,
			   "Schemas: unexpected element %s here \n",
			   child->name, NULL);
	    child = child->next;
	}
	while (IS_SCHEMA(child, "annotation")) {
	    annot = xmlSchemaParseAnnotation(ctxt, schema, child);
	    if (schema->annot == NULL)
		schema->annot = annot;
	    else
		xmlSchemaFreeAnnot(annot);
	    child = child->next;
	}
    }
}

/**
 * xmlSchemaParseInclude:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema Include definition
 *
 * Returns -1 in case of error, 0 if the declaration is inproper and
 *         1 in case of success.
 */
static int
xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                      xmlNodePtr node)
{
    xmlNodePtr child = NULL;
    const xmlChar *schemaLocation;
    xmlURIPtr check;
    xmlDocPtr doc;
    xmlNodePtr root;
    xmlSchemaIncludePtr include;


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

    /*
     * Preliminary step, extract the URI-Reference for the include and
     * make an URI from the base.
     */
    schemaLocation = xmlSchemaGetProp(ctxt, node, "schemaLocation");
    if (schemaLocation != NULL) {
        xmlChar *base = NULL;
        xmlChar *URI = NULL;
        check = xmlParseURI((const char *) schemaLocation);
        if (check == NULL) {
            xmlSchemaPErr2(ctxt, node, child,
                           XML_SCHEMAP_INCLUDE_SCHEMA_NOT_URI,
		       "Include schemaLocation attribute is not an URI: %s\n",
                           schemaLocation, NULL);
            return (-1);
        } else {
            xmlFreeURI(check);
        }
	base = xmlNodeGetBase(node->doc, node);
	if (base == NULL) {
	    URI = xmlBuildURI(schemaLocation, node->doc->URL);
	} else {
	    URI = xmlBuildURI(schemaLocation, base);
	    xmlFree(base);
	}
	if (URI != NULL) {
	    schemaLocation = xmlDictLookup(ctxt->dict, URI, -1);
	    xmlFree(URI);
	}
    } else {
	xmlSchemaPErr2(ctxt, node, child,
		       XML_SCHEMAP_INCLUDE_SCHEMA_NO_URI,
		   "Include schemaLocation attribute missing\n",
		       NULL, NULL);
	return (-1);
    }

    child = node->children;
    while (IS_SCHEMA(child, "annotation")) {
        /*
         * the annotations here are simply discarded ...
         */
        child = child->next;
    }
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_INCLUDE_CHILD,
                       "Include has unexpected content\n", NULL, NULL);
        return (-1);
    }

    /*
     * First step is to parse the input document into an DOM/Infoset
     */
    doc = xmlReadFile((const char *) schemaLocation, NULL,
                      SCHEMAS_PARSE_OPTIONS);
    if (doc == NULL) {
	xmlSchemaPErr(ctxt, NULL,
		      XML_SCHEMAP_FAILED_LOAD,
		      "xmlSchemaParse: could not load %s\n",
		      ctxt->URL, NULL);
	return(-1);
    }

    /*
     * Then extract the root of the schema
     */
    root = xmlDocGetRootElement(doc);
    if (root == NULL) {
	xmlSchemaPErr(ctxt, (xmlNodePtr) doc,
		      XML_SCHEMAP_NOROOT,
		      "schemas %s has no root", schemaLocation, NULL);
	xmlFreeDoc(doc);
        return (-1);
    }

    /*
     * Remove all the blank text nodes
     */
    xmlSchemaCleanupDoc(ctxt, root);

    /*
     * Check the schemas top level element
     */
    if (!IS_SCHEMA(root, "schema")) {
	xmlSchemaPErr(ctxt, (xmlNodePtr) doc,
		      XML_SCHEMAP_NOT_SCHEMA,
		      "File %s is not a schemas", schemaLocation, NULL);
	xmlFreeDoc(doc);
        return (-1);
    }

    /*
     * register the include
     */
    include = (xmlSchemaIncludePtr) xmlMalloc(sizeof(xmlSchemaInclude));
    if (include == NULL) {
        xmlSchemaPErrMemory(ctxt, "allocating included schema", NULL);
	xmlFreeDoc(doc);
        return (-1);
    }

    memset(include, 0, sizeof(xmlSchemaInclude));
    include->schemaLocation = xmlDictLookup(ctxt->dict, schemaLocation, -1);
    include->doc = doc;
    include->next = schema->includes;
    schema->includes = include;


    /*
     * parse the declarations in the included file like if they
     * were in the original file.
     */
    xmlSchemaParseSchemaTopLevel(ctxt, schema, root->children);

    return (1);
}

/**
 * xmlSchemaParseChoice:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema Choice definition
 * *WARNING* this interface is highly subject to change
 *
 * Returns -1 in case of error, 0 if the declaration is inproper and
 *         1 in case of success.
 */
static xmlSchemaTypePtr
xmlSchemaParseChoice(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                     xmlNodePtr node)
{
    xmlSchemaTypePtr type, subtype, last = NULL;
    xmlNodePtr child = NULL;
    xmlChar name[30];

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
        return (NULL);


    snprintf((char *) name, 30, "choice %d", ctxt->counter++ + 1);
    type = xmlSchemaAddType(ctxt, schema, name, NULL);
    if (type == NULL)
        return (NULL);
    type->node = node;
    type->type = XML_SCHEMA_TYPE_CHOICE;
    type->id = xmlSchemaGetProp(ctxt, node, "id");
    type->minOccurs = xmlGetMinOccurs(ctxt, node);
    type->maxOccurs = xmlGetMaxOccurs(ctxt, node);

    child = node->children;
    if (IS_SCHEMA(child, "annotation")) {
        type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
        child = child->next;
    }
    while ((IS_SCHEMA(child, "element")) ||
           (IS_SCHEMA(child, "group")) ||
           (IS_SCHEMA(child, "any")) ||
           (IS_SCHEMA(child, "choice")) ||
           (IS_SCHEMA(child, "sequence"))) {
        subtype = NULL;
        if (IS_SCHEMA(child, "element")) {
            subtype = (xmlSchemaTypePtr)
                xmlSchemaParseElement(ctxt, schema, child, 0);
        } else if (IS_SCHEMA(child, "group")) {
            subtype = xmlSchemaParseGroup(ctxt, schema, child);
        } else if (IS_SCHEMA(child, "any")) {
            subtype = xmlSchemaParseAny(ctxt, schema, child);
        } else if (IS_SCHEMA(child, "sequence")) {
            subtype = xmlSchemaParseSequence(ctxt, schema, child);
        } else if (IS_SCHEMA(child, "choice")) {
            subtype = xmlSchemaParseChoice(ctxt, schema, child);
        }
        if (subtype != NULL) {
            if (last == NULL) {
                type->subtypes = subtype;
                last = subtype;
            } else {
                last->next = subtype;
                last = subtype;
            }
            last->next = NULL;
        }
        child = child->next;
    }
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_CHOICE_CHILD,
                       "Choice %s has unexpected content\n", type->name,
                       NULL);
    }

    return (type);
}

/**
 * xmlSchemaParseSequence:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema Sequence definition
 * *WARNING* this interface is highly subject to change
 *
 * Returns -1 in case of error, 0 if the declaration is inproper and
 *         1 in case of success.
 */
static xmlSchemaTypePtr
xmlSchemaParseSequence(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                       xmlNodePtr node)
{
    xmlSchemaTypePtr type, subtype, last = NULL;
    xmlNodePtr child = NULL;
    xmlChar name[30];

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
        return (NULL);


    snprintf((char *) name, 30, "sequence %d", ctxt->counter++ + 1);
    type = xmlSchemaAddType(ctxt, schema, name, NULL);
    if (type == NULL)
        return (NULL);
    type->node = node;
    type->type = XML_SCHEMA_TYPE_SEQUENCE;
    type->id = xmlSchemaGetProp(ctxt, node, "id");
    type->minOccurs = xmlGetMinOccurs(ctxt, node);
    type->maxOccurs = xmlGetMaxOccurs(ctxt, node);

    child = node->children;
    if (IS_SCHEMA(child, "annotation")) {
        type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
        child = child->next;
    }
    while ((IS_SCHEMA(child, "element")) ||
           (IS_SCHEMA(child, "group")) ||
           (IS_SCHEMA(child, "any")) ||
           (IS_SCHEMA(child, "choice")) ||
           (IS_SCHEMA(child, "sequence"))) {
        subtype = NULL;
        if (IS_SCHEMA(child, "element")) {
            subtype = (xmlSchemaTypePtr)
                xmlSchemaParseElement(ctxt, schema, child, 0);
        } else if (IS_SCHEMA(child, "group")) {
            subtype = xmlSchemaParseGroup(ctxt, schema, child);
        } else if (IS_SCHEMA(child, "any")) {
            subtype = xmlSchemaParseAny(ctxt, schema, child);
        } else if (IS_SCHEMA(child, "choice")) {
            subtype = xmlSchemaParseChoice(ctxt, schema, child);
        } else if (IS_SCHEMA(child, "sequence")) {
            subtype = xmlSchemaParseSequence(ctxt, schema, child);
        }
        if (subtype != NULL) {
            if (last == NULL) {
                type->subtypes = subtype;
                last = subtype;
            } else {
                last->next = subtype;
                last = subtype;
            }
            last->next = NULL;
        }
        child = child->next;
    }
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child,
                       XML_SCHEMAP_UNKNOWN_SEQUENCE_CHILD,
                       "Sequence %s has unexpected content\n", type->name,
                       NULL);
    }

    return (type);
}

/**
 * xmlSchemaParseRestriction:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 * @simple:  is that part of a simple type.
 *
 * parse a XML schema Restriction definition
 * *WARNING* this interface is highly subject to change
 *
 * Returns the type definition or NULL in case of error
 */
static xmlSchemaTypePtr
xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                          xmlNodePtr node, int simple)
{
    xmlSchemaTypePtr type, subtype;
    xmlSchemaFacetPtr facet, lastfacet = NULL;
    xmlNodePtr child = NULL;
    xmlChar name[30];
    const xmlChar *oldcontainer;

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
        return (NULL);

    oldcontainer = ctxt->container;

    snprintf((char *) name, 30, "restriction %d", ctxt->counter++ + 1);
    type = xmlSchemaAddType(ctxt, schema, name, NULL);
    if (type == NULL)
        return (NULL);
    type->node = node;
    type->type = XML_SCHEMA_TYPE_RESTRICTION;
    type->id = xmlSchemaGetProp(ctxt, node, "id");
    type->base = xmlGetQNameProp(ctxt, node, "base", &(type->baseNs));
    if ((!simple) && (type->base == NULL)) {
        xmlSchemaPErr2(ctxt, node, child,
                       XML_SCHEMAP_RESTRICTION_NONAME_NOREF,
                       "Restriction %s has no base\n", type->name, NULL);
    }
    ctxt->container = name;

    child = node->children;
    if (IS_SCHEMA(child, "annotation")) {
        type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
        child = child->next;
    }
    subtype = NULL;

    if (IS_SCHEMA(child, "all")) {
        subtype = (xmlSchemaTypePtr)
            xmlSchemaParseAll(ctxt, schema, child);
        child = child->next;
        type->subtypes = subtype;
    } else if (IS_SCHEMA(child, "choice")) {
        subtype = xmlSchemaParseChoice(ctxt, schema, child);
        child = child->next;
        type->subtypes = subtype;
    } else if (IS_SCHEMA(child, "sequence")) {
        subtype = (xmlSchemaTypePtr)
            xmlSchemaParseSequence(ctxt, schema, child);
        child = child->next;
        type->subtypes = subtype;
    } else if (IS_SCHEMA(child, "group")) {
        subtype = (xmlSchemaTypePtr)
            xmlSchemaParseGroup(ctxt, schema, child);
        child = child->next;
        type->subtypes = subtype;
    } else {
        if (IS_SCHEMA(child, "simpleType")) {
            subtype = (xmlSchemaTypePtr)
                xmlSchemaParseSimpleType(ctxt, schema, child);
            child = child->next;
            type->baseType = subtype;
        }
        /*
         * Facets
         */
        while ((IS_SCHEMA(child, "minInclusive")) ||
               (IS_SCHEMA(child, "minExclusive")) ||
               (IS_SCHEMA(child, "maxInclusive")) ||
               (IS_SCHEMA(child, "maxExclusive")) ||
               (IS_SCHEMA(child, "totalDigits")) ||
               (IS_SCHEMA(child, "fractionDigits")) ||
               (IS_SCHEMA(child, "pattern")) ||
               (IS_SCHEMA(child, "enumeration")) ||
               (IS_SCHEMA(child, "whiteSpace")) ||
               (IS_SCHEMA(child, "length")) ||
               (IS_SCHEMA(child, "maxLength")) ||
               (IS_SCHEMA(child, "minLength"))) {
            facet = xmlSchemaParseFacet(ctxt, schema, child);
            if (facet != NULL) {
                if (lastfacet == NULL) {
                    type->facets = facet;
                    lastfacet = facet;
                } else {
                    lastfacet->next = facet;
                    lastfacet = facet;
                }
                lastfacet->next = NULL;
            }
            child = child->next;
        }
    }
    child = xmlSchemaParseAttrDecls(ctxt, schema, child, type);
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child,
                       XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD,
                       "Restriction %s has unexpected content\n",
                       type->name, NULL);
    }
    ctxt->container = oldcontainer;
    return (type);
}

/**
 * xmlSchemaParseExtension:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema Extension definition
 * *WARNING* this interface is highly subject to change
 *
 * Returns the type definition or NULL in case of error
 */
static xmlSchemaTypePtr
xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                        xmlNodePtr node)
{
    xmlSchemaTypePtr type, subtype;
    xmlNodePtr child = NULL;
    xmlChar name[30];
    const xmlChar *oldcontainer;

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
        return (NULL);

    oldcontainer = ctxt->container;

    snprintf((char *) name, 30, "extension %d", ctxt->counter++ + 1);
    type = xmlSchemaAddType(ctxt, schema, name, NULL);
    if (type == NULL)
        return (NULL);
    type->node = node;
    type->type = XML_SCHEMA_TYPE_EXTENSION;
    type->id = xmlSchemaGetProp(ctxt, node, "id");
    ctxt->container = name;

    type->base = xmlGetQNameProp(ctxt, node, "base", &(type->baseNs));
    if (type->base == NULL) {
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_EXTENSION_NO_BASE,
                       "Extension %s has no base\n", type->name, NULL);
    }
    child = node->children;
    if (IS_SCHEMA(child, "annotation")) {
        type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
        child = child->next;
    }
    subtype = NULL;

    if (IS_SCHEMA(child, "all")) {
        subtype = xmlSchemaParseAll(ctxt, schema, child);
        child = child->next;
    } else if (IS_SCHEMA(child, "choice")) {
        subtype = xmlSchemaParseChoice(ctxt, schema, child);
        child = child->next;
    } else if (IS_SCHEMA(child, "sequence")) {
        subtype = xmlSchemaParseSequence(ctxt, schema, child);
        child = child->next;
    } else if (IS_SCHEMA(child, "group")) {
        subtype = xmlSchemaParseGroup(ctxt, schema, child);
        child = child->next;
    }
    if (subtype != NULL)
        type->subtypes = subtype;
    child = xmlSchemaParseAttrDecls(ctxt, schema, child, type);
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child,
                       XML_SCHEMAP_UNKNOWN_EXTENSION_CHILD,
                       "Extension %s has unexpected content\n", type->name,
                       NULL);
    }
    ctxt->container = oldcontainer;
    return (type);
}

/**
 * xmlSchemaParseSimpleContent:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema SimpleContent definition
 * *WARNING* this interface is highly subject to change
 *
 * Returns the type definition or NULL in case of error
 */
static xmlSchemaTypePtr
xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
                            xmlSchemaPtr schema, xmlNodePtr node)
{
    xmlSchemaTypePtr type, subtype;
    xmlNodePtr child = NULL;
    xmlChar name[30];

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
        return (NULL);


    snprintf((char *) name, 30, "complexContent %d", ctxt->counter++ + 1);
    type = xmlSchemaAddType(ctxt, schema, name, NULL);
    if (type == NULL)
        return (NULL);
    type->node = node;
    type->type = XML_SCHEMA_TYPE_SIMPLE_CONTENT;
    type->id = xmlSchemaGetProp(ctxt, node, "id");

    child = node->children;
    if (IS_SCHEMA(child, "annotation")) {
        type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
        child = child->next;
    }
    subtype = NULL;
    if (IS_SCHEMA(child, "restriction")) {
        subtype = (xmlSchemaTypePtr)
            xmlSchemaParseRestriction(ctxt, schema, child, 0);
        child = child->next;
    } else if (IS_SCHEMA(child, "extension")) {
        subtype = (xmlSchemaTypePtr)
            xmlSchemaParseExtension(ctxt, schema, child);
        child = child->next;
    }
    type->subtypes = subtype;
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child,
                       XML_SCHEMAP_UNKNOWN_SIMPLECONTENT_CHILD,
                       "SimpleContent %s has unexpected content\n",
                       type->name, NULL);
    }
    return (type);
}

/**
 * xmlSchemaParseComplexContent:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema ComplexContent definition
 * *WARNING* this interface is highly subject to change
 *
 * Returns the type definition or NULL in case of error
 */
static xmlSchemaTypePtr
xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
                             xmlSchemaPtr schema, xmlNodePtr node)
{
    xmlSchemaTypePtr type, subtype;
    xmlNodePtr child = NULL;
    xmlChar name[30];

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
        return (NULL);


    snprintf((char *) name, 30, "complexContent %d", ctxt->counter++ + 1);
    type = xmlSchemaAddType(ctxt, schema, name, NULL);
    if (type == NULL)
        return (NULL);
    type->node = node;
    type->type = XML_SCHEMA_TYPE_COMPLEX_CONTENT;
    type->id = xmlSchemaGetProp(ctxt, node, "id");

    child = node->children;
    if (IS_SCHEMA(child, "annotation")) {
        type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
        child = child->next;
    }
    subtype = NULL;
    if (IS_SCHEMA(child, "restriction")) {
        subtype = (xmlSchemaTypePtr)
            xmlSchemaParseRestriction(ctxt, schema, child, 0);
        child = child->next;
    } else if (IS_SCHEMA(child, "extension")) {
        subtype = (xmlSchemaTypePtr)
            xmlSchemaParseExtension(ctxt, schema, child);
        child = child->next;
    }
    type->subtypes = subtype;
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child,
                       XML_SCHEMAP_UNKNOWN_COMPLEXCONTENT_CHILD,
                       "ComplexContent %s has unexpected content\n",
                       type->name, NULL);
    }
    return (type);
}

/**
 * xmlSchemaParseComplexType:
 * @ctxt:  a schema validation context
 * @schema:  the schema being built
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema Complex Type definition
 * *WARNING* this interface is highly subject to change
 *
 * Returns the type definition or NULL in case of error
 */
static xmlSchemaTypePtr
xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                          xmlNodePtr node)
{
    xmlSchemaTypePtr type, subtype;
    xmlNodePtr child = NULL;
    const xmlChar *name;
    const xmlChar *oldcontainer;
    const xmlChar *mixed;
    char buf[100];

    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
        return (NULL);

    oldcontainer = ctxt->container;
    name = xmlSchemaGetProp(ctxt, node, "name");
    if (name == NULL) {

        snprintf(buf, 99, "anontype %d", ctxt->counter++ + 1);
	name = (const xmlChar *)buf;
	type = xmlSchemaAddType(ctxt, schema, name, NULL);
    } else {
	const xmlChar *local, *ns;

        local = xmlSchemaGetNamespace(ctxt, schema, node, name, &ns);
	type = xmlSchemaAddType(ctxt, schema, local, ns);
    }
    if (type == NULL) {
        return (NULL);
    }

    mixed = xmlSchemaGetProp(ctxt, node, "mixed");
    if (mixed != NULL)
	type->flags |= XML_SCHEMAS_TYPE_MIXED;

    type->node = node;
    type->type = XML_SCHEMA_TYPE_COMPLEX;
    type->id = xmlSchemaGetProp(ctxt, node, "id");
    ctxt->container = name;

    child = node->children;
    if (IS_SCHEMA(child, "annotation")) {
        type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
        child = child->next;
    }
    if (IS_SCHEMA(child, "simpleContent")) {
        type->subtypes = xmlSchemaParseSimpleContent(ctxt, schema, child);
        child = child->next;
    } else if (IS_SCHEMA(child, "complexContent")) {
        type->subtypes = xmlSchemaParseComplexContent(ctxt, schema, child);
        child = child->next;
    } else {
        subtype = NULL;

        if (IS_SCHEMA(child, "all")) {
            subtype = xmlSchemaParseAll(ctxt, schema, child);
            child = child->next;
        } else if (IS_SCHEMA(child, "choice")) {
            subtype = xmlSchemaParseChoice(ctxt, schema, child);
            child = child->next;
        } else if (IS_SCHEMA(child, "sequence")) {
            subtype = xmlSchemaParseSequence(ctxt, schema, child);
            child = child->next;
        } else if (IS_SCHEMA(child, "group")) {
            subtype = xmlSchemaParseGroup(ctxt, schema, child);
            child = child->next;
        }
        if (subtype != NULL)
            type->subtypes = subtype;
        child = xmlSchemaParseAttrDecls(ctxt, schema, child, type);
    }
    if (child != NULL) {
        xmlSchemaPErr2(ctxt, node, child,
                       XML_SCHEMAP_UNKNOWN_COMPLEXTYPE_CHILD,
                       "ComplexType %s has unexpected content\n",
                       type->name, NULL);
    }
    ctxt->container = oldcontainer;
    return (type);
}

/**
 * xmlSchemaParseSchema:
 * @ctxt:  a schema validation context
 * @node:  a subtree containing XML Schema informations
 *
 * parse a XML schema definition from a node set
 * *WARNING* this interface is highly subject to change
 *
 * Returns the internal XML Schema structure built from the resource or
 *         NULL in case of error
 */
static xmlSchemaPtr
xmlSchemaParseSchema(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
{
    xmlSchemaPtr schema = NULL;
    xmlNodePtr child = NULL;
    const xmlChar *val;
    int nberrors;

    if ((ctxt == NULL) || (node == NULL))
        return (NULL);

    nberrors = ctxt->nberrors;
    ctxt->nberrors = 0;
    if (IS_SCHEMA(node, "schema")) {
        schema = xmlSchemaNewSchema(ctxt);
        if (schema == NULL)
            return (NULL);
	val = xmlSchemaGetProp(ctxt, node, "targetNamespace");
	if (val != NULL) {
	    schema->targetNamespace = xmlDictLookup(ctxt->dict, val, -1);
	} else {
	    schema->targetNamespace = NULL;
	}
        schema->id = xmlSchemaGetProp(ctxt, node, "id");
        schema->version = xmlSchemaGetProp(ctxt, node, "version");
        val = xmlSchemaGetProp(ctxt, node, "elementFormDefault");
        if (val != NULL) {
            if (xmlStrEqual(val, BAD_CAST "qualified"))
                schema->flags |= XML_SCHEMAS_QUALIF_ELEM;
            else if (!xmlStrEqual(val, BAD_CAST "unqualified")) {
                xmlSchemaPErr2(ctxt, node, child,
                               XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
                               "Invalid value %s for elementFormDefault\n",
                               val, NULL);
            }
        } else {
	    schema->flags |= XML_SCHEMAS_QUALIF_ELEM;
	}
        val = xmlSchemaGetProp(ctxt, node, "attributeFormDefault");
        if (val != NULL) {
            if (xmlStrEqual(val, BAD_CAST "qualified"))
                schema->flags |= XML_SCHEMAS_QUALIF_ATTR;
            else if (!xmlStrEqual(val, BAD_CAST "unqualified")) {
                xmlSchemaPErr2(ctxt, node, child,
                               XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
                               "Invalid value %s for attributeFormDefault\n",
                               val, NULL);
            }
        } 

        xmlSchemaParseSchemaTopLevel(ctxt, schema, node->children);
    } else {
        xmlDocPtr doc;

	doc = node->doc;

        if ((doc != NULL) && (doc->URL != NULL)) {
	    xmlSchemaPErr(ctxt, (xmlNodePtr) doc,
		      XML_SCHEMAP_NOT_SCHEMA,
		      "File %s is not a schemas", doc->URL, NULL);
	} else {
	    xmlSchemaPErr(ctxt, (xmlNodePtr) doc,
		      XML_SCHEMAP_NOT_SCHEMA,
		      "File is not a schemas", NULL, NULL);
	}
	return(NULL);
    }
    if (ctxt->nberrors != 0) {
        if (schema != NULL) {
            xmlSchemaFree(schema);
            schema = NULL;
        }
    }
    ctxt->nberrors = nberrors;
#ifdef DEBUG
    if (schema == NULL)
        xmlGenericError(xmlGenericErrorContext,
                        "xmlSchemaParse() failed\n");
#endif

    return (schema);
}

/************************************************************************
 * 									*
 * 			Validating using Schemas			*
 * 									*
 ************************************************************************/

/************************************************************************
 * 									*
 * 			Reading/Writing Schemas				*
 * 									*
 ************************************************************************/

/**
 * xmlSchemaNewParserCtxt:
 * @URL:  the location of the schema
 *
 * Create an XML Schemas parse context for that file/resource expected
 * to contain an XML Schemas file.
 *
 * Returns the parser context or NULL in case of error
 */
xmlSchemaParserCtxtPtr
xmlSchemaNewParserCtxt(const char *URL)
{
    xmlSchemaParserCtxtPtr ret;

    if (URL == NULL)
        return (NULL);

    ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
    if (ret == NULL) {
        xmlSchemaPErrMemory(NULL, "allocating schama parser context",
                            NULL);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchemaParserCtxt));
    ret->dict = xmlDictCreate();
    ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
    ret->includes = 0;
    return (ret);
}

/**
 * xmlSchemaNewMemParserCtxt:
 * @buffer:  a pointer to a char array containing the schemas
 * @size:  the size of the array
 *
 * Create an XML Schemas parse context for that memory buffer expected
 * to contain an XML Schemas file.
 *
 * Returns the parser context or NULL in case of error
 */
xmlSchemaParserCtxtPtr
xmlSchemaNewMemParserCtxt(const char *buffer, int size)
{
    xmlSchemaParserCtxtPtr ret;

    if ((buffer == NULL) || (size <= 0))
        return (NULL);

    ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
    if (ret == NULL) {
        xmlSchemaPErrMemory(NULL, "allocating schama parser context",
                            NULL);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchemaParserCtxt));
    ret->buffer = buffer;
    ret->size = size;
    ret->dict = xmlDictCreate();
    return (ret);
}

/**
 * xmlSchemaNewDocParserCtxt:
 * @doc:  a preparsed document tree
 *
 * Create an XML Schemas parse context for that document.
 * NB. The document may be modified during the parsing process.
 *
 * Returns the parser context or NULL in case of error
 */
xmlSchemaParserCtxtPtr
xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
{
    xmlSchemaParserCtxtPtr ret;

    if (doc == NULL)
      return (NULL);

    ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
    if (ret == NULL) {
      xmlSchemaPErrMemory(NULL, "allocating schema parser context",
			  NULL);
      return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchemaParserCtxt));
    ret->doc = doc;
    ret->dict = xmlDictCreate();
    /* The application has responsibility for the document */
    ret->preserve = 1;

    return (ret);
}

/**
 * xmlSchemaFreeParserCtxt:
 * @ctxt:  the schema parser context
 *
 * Free the resources associated to the schema parser context
 */
void
xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
{
    if (ctxt == NULL)
        return;
    if (ctxt->doc != NULL && !ctxt->preserve)
        xmlFreeDoc(ctxt->doc);
    xmlDictFree(ctxt->dict);
    xmlFree(ctxt);
}

/************************************************************************
 *									*
 *			Building the content models			*
 *									*
 ************************************************************************/

/**
 * xmlSchemaBuildAContentModel:
 * @type:  the schema type definition
 * @ctxt:  the schema parser context
 * @name:  the element name whose content is being built
 *
 * Generate the automata sequence needed for that type
 */
static void
xmlSchemaBuildAContentModel(xmlSchemaTypePtr type,
                            xmlSchemaParserCtxtPtr ctxt,
                            const xmlChar * name)
{
    if (type == NULL) {
        xmlGenericError(xmlGenericErrorContext,
                        "Found unexpected type = NULL in %s content model\n",
                        name);
        return;
    }
    switch (type->type) {
        case XML_SCHEMA_TYPE_ANY:
            /* TODO : handle the namespace too */
            /* TODO : make that a specific transition type */
            TODO ctxt->state =
                xmlAutomataNewTransition(ctxt->am, ctxt->state, NULL,
                                         BAD_CAST "*", NULL);
            break;
        case XML_SCHEMA_TYPE_ELEMENT:{
                xmlSchemaElementPtr elem = (xmlSchemaElementPtr) type;

                /* TODO : handle the namespace too */
                xmlAutomataStatePtr oldstate = ctxt->state;

                if (elem->maxOccurs >= UNBOUNDED) {
                    if (elem->minOccurs > 1) {
                        xmlAutomataStatePtr tmp;
                        int counter;

                        ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
                                                            oldstate,
                                                            NULL);
                        oldstate = ctxt->state;

                        counter = xmlAutomataNewCounter(ctxt->am,
                                                        elem->minOccurs -
                                                        1, UNBOUNDED);

                        if (elem->refDecl != NULL) {
                            xmlSchemaBuildAContentModel((xmlSchemaTypePtr)
                                                        elem->refDecl,
                                                        ctxt,
                                                        elem->refDecl->
                                                        name);
                        } else {
                            ctxt->state =
                                xmlAutomataNewTransition(ctxt->am,
                                                         ctxt->state, NULL,
                                                         elem->name, type);
                        }
                        tmp = ctxt->state;
                        xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate,
                                                   counter);
                        ctxt->state =
                            xmlAutomataNewCounterTrans(ctxt->am, tmp, NULL,
                                                       counter);

                    } else {
                        if (elem->refDecl != NULL) {
                            xmlSchemaBuildAContentModel((xmlSchemaTypePtr)
                                                        elem->refDecl,
                                                        ctxt,
                                                        elem->refDecl->
                                                        name);
                        } else {
                            ctxt->state =
                                xmlAutomataNewTransition(ctxt->am,
                                                         ctxt->state, NULL,
                                                         elem->name, type);
                        }
                        xmlAutomataNewEpsilon(ctxt->am, ctxt->state,
                                              oldstate);
                        if (elem->minOccurs == 0) {
                            /* basically an elem* */
                            xmlAutomataNewEpsilon(ctxt->am, oldstate,
                                                  ctxt->state);
                        }
                    }
                } else if ((elem->maxOccurs > 1) || (elem->minOccurs > 1)) {
                    xmlAutomataStatePtr tmp;
                    int counter;

                    ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
                                                        oldstate, NULL);
                    oldstate = ctxt->state;

                    counter = xmlAutomataNewCounter(ctxt->am,
                                                    elem->minOccurs - 1,
                                                    elem->maxOccurs - 1);

                    if (elem->refDecl != NULL) {
                        xmlSchemaBuildAContentModel((xmlSchemaTypePtr)
                                                    elem->refDecl, ctxt,
                                                    elem->refDecl->name);
                    } else {
                        ctxt->state = xmlAutomataNewTransition(ctxt->am,
                                                               ctxt->state,
                                                               NULL,
                                                               elem->name,
                                                               type);
                    }
                    tmp = ctxt->state;
                    xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate,
                                               counter);
                    ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, tmp,
                                                             NULL,
                                                             counter);
                    if (elem->minOccurs == 0) {
                        /* basically an elem? */
                        xmlAutomataNewEpsilon(ctxt->am, oldstate,
                                              ctxt->state);
                    }

                } else {
                    if (elem->refDecl != NULL) {
                        xmlSchemaBuildAContentModel((xmlSchemaTypePtr)
                                                    elem->refDecl, ctxt,
                                                    elem->refDecl->name);
                    } else {
                        ctxt->state = xmlAutomataNewTransition(ctxt->am,
                                                               ctxt->state,
                                                               NULL,
                                                               elem->name,
                                                               type);
                    }
                    if (elem->minOccurs == 0) {
                        /* basically an elem? */
                        xmlAutomataNewEpsilon(ctxt->am, oldstate,
                                              ctxt->state);
                    }
                }
                break;
            }
        case XML_SCHEMA_TYPE_SEQUENCE:{
                xmlSchemaTypePtr subtypes;

                /*
                 * If max and min occurances are default (1) then
                 * simply iterate over the subtypes
                 */
                if ((type->minOccurs == 1) && (type->maxOccurs == 1)) {
                    subtypes = type->subtypes;
                    while (subtypes != NULL) {
                        xmlSchemaBuildAContentModel(subtypes, ctxt, name);
                        subtypes = subtypes->next;
                    }
                } else {
                    xmlAutomataStatePtr oldstate = ctxt->state;

                    if (type->maxOccurs >= UNBOUNDED) {
                        if (type->minOccurs > 1) {
                            xmlAutomataStatePtr tmp;
                            int counter;

                            ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
                                                                oldstate,
                                                                NULL);
                            oldstate = ctxt->state;

                            counter = xmlAutomataNewCounter(ctxt->am,
                                                            type->
                                                            minOccurs - 1,
                                                            UNBOUNDED);

                            subtypes = type->subtypes;
                            while (subtypes != NULL) {
                                xmlSchemaBuildAContentModel(subtypes, ctxt,
                                                            name);
                                subtypes = subtypes->next;
                            }
                            tmp = ctxt->state;
                            xmlAutomataNewCountedTrans(ctxt->am, tmp,
                                                       oldstate, counter);
                            ctxt->state =
                                xmlAutomataNewCounterTrans(ctxt->am, tmp,
                                                           NULL, counter);

                        } else {
                            subtypes = type->subtypes;
                            while (subtypes != NULL) {
                                xmlSchemaBuildAContentModel(subtypes, ctxt,
                                                            name);
                                subtypes = subtypes->next;
                            }
                            xmlAutomataNewEpsilon(ctxt->am, ctxt->state,
                                                  oldstate);
                            if (type->minOccurs == 0) {
                                xmlAutomataNewEpsilon(ctxt->am, oldstate,
                                                      ctxt->state);
                            }
                        }
                    } else if ((type->maxOccurs > 1)
                               || (type->minOccurs > 1)) {
                        xmlAutomataStatePtr tmp;
                        int counter;

                        ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
                                                            oldstate,
                                                            NULL);
                        oldstate = ctxt->state;

                        counter = xmlAutomataNewCounter(ctxt->am,
                                                        type->minOccurs -
                                                        1,
                                                        type->maxOccurs -
                                                        1);

                        subtypes = type->subtypes;
                        while (subtypes != NULL) {
                            xmlSchemaBuildAContentModel(subtypes, ctxt,
                                                        name);
                            subtypes = subtypes->next;
                        }
                        tmp = ctxt->state;
                        xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate,
                                                   counter);
                        ctxt->state =
                            xmlAutomataNewCounterTrans(ctxt->am, tmp, NULL,
                                                       counter);
                        if (type->minOccurs == 0) {
                            xmlAutomataNewEpsilon(ctxt->am, oldstate,
                                                  ctxt->state);
                        }

                    } else {
                        subtypes = type->subtypes;
                        while (subtypes != NULL) {
                            xmlSchemaBuildAContentModel(subtypes, ctxt,
                                                        name);
                            subtypes = subtypes->next;
                        }
                        if (type->minOccurs == 0) {
                            xmlAutomataNewEpsilon(ctxt->am, oldstate,
                                                  ctxt->state);
                        }
                    }
                }
                break;
            }
        case XML_SCHEMA_TYPE_CHOICE:{
                xmlSchemaTypePtr subtypes;
                xmlAutomataStatePtr start, end;

                start = ctxt->state;
                end = xmlAutomataNewState(ctxt->am);

                /*
                 * iterate over the subtypes and remerge the end with an
                 * epsilon transition
                 */
                if (type->maxOccurs == 1) {
                    subtypes = type->subtypes;
                    while (subtypes != NULL) {
                        ctxt->state = start;
                        xmlSchemaBuildAContentModel(subtypes, ctxt, name);
                        xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end);
                        subtypes = subtypes->next;
                    }
                } else {
                    int counter;
                    xmlAutomataStatePtr hop;
                    int maxOccurs = type->maxOccurs == UNBOUNDED ?
                        UNBOUNDED : type->maxOccurs - 1;
                    int minOccurs =
                        type->minOccurs < 1 ? 0 : type->minOccurs - 1;

                    /*
                     * use a counter to keep track of the number of transtions
                     * which went through the choice.
                     */
                    counter =
                        xmlAutomataNewCounter(ctxt->am, minOccurs,
                                              maxOccurs);
                    hop = xmlAutomataNewState(ctxt->am);

                    subtypes = type->subtypes;
                    while (subtypes != NULL) {
                        ctxt->state = start;
                        xmlSchemaBuildAContentModel(subtypes, ctxt, name);
                        xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop);
                        subtypes = subtypes->next;
                    }
                    xmlAutomataNewCountedTrans(ctxt->am, hop, start,
                                               counter);
                    xmlAutomataNewCounterTrans(ctxt->am, hop, end,
                                               counter);
                }
                if (type->minOccurs == 0) {
                    xmlAutomataNewEpsilon(ctxt->am, start, end);
                }
                ctxt->state = end;
                break;
            }
        case XML_SCHEMA_TYPE_ALL:{
                xmlAutomataStatePtr start;
                xmlSchemaTypePtr subtypes;
                xmlSchemaElementPtr elem = (xmlSchemaElementPtr) type;
                int lax;

                subtypes = type->subtypes;
                if (subtypes == NULL)
                    break;
                start = ctxt->state;
                while (subtypes != NULL) {
                    ctxt->state = start;
                    elem = (xmlSchemaElementPtr) subtypes;

                    /* TODO : handle the namespace too */
                    if ((elem->minOccurs == 1) && (elem->maxOccurs == 1)) {
                        xmlAutomataNewOnceTrans(ctxt->am, ctxt->state,
                                                ctxt->state, elem->name, 1,
                                                1, subtypes);
                    } else {
                        xmlAutomataNewCountTrans(ctxt->am, ctxt->state,
                                                 ctxt->state, elem->name,
                                                 elem->minOccurs,
                                                 elem->maxOccurs,
                                                 subtypes);
                    }
                    subtypes = subtypes->next;
                }
                lax = type->minOccurs == 0;
                ctxt->state =
                    xmlAutomataNewAllTrans(ctxt->am, ctxt->state, NULL,
                                           lax);
                break;
            }
        case XML_SCHEMA_TYPE_RESTRICTION:
            if (type->subtypes != NULL)
                xmlSchemaBuildAContentModel(type->subtypes, ctxt, name);
            break;
        case XML_SCHEMA_TYPE_EXTENSION:
            if (type->baseType != NULL) {
                xmlSchemaTypePtr subtypes;

                xmlSchemaBuildAContentModel(type->baseType, ctxt, name);
                subtypes = type->subtypes;
                while (subtypes != NULL) {
                    xmlSchemaBuildAContentModel(subtypes, ctxt, name);
                    subtypes = subtypes->next;
                }
            } else if (type->subtypes != NULL)
                xmlSchemaBuildAContentModel(type->subtypes, ctxt, name);
            break;
        case XML_SCHEMA_TYPE_GROUP:
            if (type->subtypes == NULL) {
            }
        case XML_SCHEMA_TYPE_COMPLEX:
        case XML_SCHEMA_TYPE_COMPLEX_CONTENT:
            if (type->subtypes != NULL)
                xmlSchemaBuildAContentModel(type->subtypes, ctxt, name);
            break;
        default:
            xmlGenericError(xmlGenericErrorContext,
                            "Found unexpected type %d in %s content model\n",
                            type->type, name);
            return;
    }
}

/**
 * xmlSchemaBuildContentModel:
 * @elem:  the element
 * @ctxt:  the schema parser context
 * @name:  the element name
 *
 * Builds the content model of the element.
 */
static void
xmlSchemaBuildContentModel(xmlSchemaElementPtr elem,
                           xmlSchemaParserCtxtPtr ctxt,
                           const xmlChar * name)
{
    xmlAutomataStatePtr start;

    if (elem->contModel != NULL)
        return;
    if (elem->subtypes == NULL) {
        elem->contentType = XML_SCHEMA_CONTENT_ANY;
        return;
    }
    if (elem->subtypes->type != XML_SCHEMA_TYPE_COMPLEX)
        return;
    if ((elem->subtypes->contentType == XML_SCHEMA_CONTENT_BASIC) ||
        (elem->subtypes->contentType == XML_SCHEMA_CONTENT_SIMPLE))
        return;

#ifdef DEBUG_CONTENT
    xmlGenericError(xmlGenericErrorContext,
                    "Building content model for %s\n", name);
#endif

    ctxt->am = xmlNewAutomata();
    if (ctxt->am == NULL) {
        xmlGenericError(xmlGenericErrorContext,
                        "Cannot create automata for elem %s\n", name);
        return;
    }
    start = ctxt->state = xmlAutomataGetInitState(ctxt->am);
    xmlSchemaBuildAContentModel(elem->subtypes, ctxt, name);
    xmlAutomataSetFinalState(ctxt->am, ctxt->state);
    elem->contModel = xmlAutomataCompile(ctxt->am);
    if (elem->contModel == NULL) {
        xmlSchemaPErr(ctxt, elem->node, XML_SCHEMAS_ERR_INTERNAL,
                      "failed to compile %s content model\n", name, NULL);
    } else if (xmlRegexpIsDeterminist(elem->contModel) != 1) {
        xmlSchemaPErr(ctxt, elem->node, XML_SCHEMAS_ERR_NOTDETERMINIST,
                      "Content model of %s is not determinist:\n", name,
                      NULL);
    } else {
#ifdef DEBUG_CONTENT_REGEXP
        xmlGenericError(xmlGenericErrorContext,
                        "Content model of %s:\n", name);
        xmlRegexpPrint(stderr, elem->contModel);
#endif
    }
    ctxt->state = NULL;
    xmlFreeAutomata(ctxt->am);
    ctxt->am = NULL;
}

/**
 * xmlSchemaRefFixupCallback:
 * @elem:  the schema element context
 * @ctxt:  the schema parser context
 *
 * Free the resources associated to the schema parser context
 */
static void
xmlSchemaRefFixupCallback(xmlSchemaElementPtr elem,
                          xmlSchemaParserCtxtPtr ctxt,
                          const xmlChar * name,
                          const xmlChar * context ATTRIBUTE_UNUSED,
                          const xmlChar * namespace ATTRIBUTE_UNUSED)
{
    if ((ctxt == NULL) || (elem == NULL))
        return;
    if (elem->ref != NULL) {
        xmlSchemaElementPtr elemDecl;

        if (elem->subtypes != NULL) {
            xmlSchemaPErr(ctxt, elem->node,
                          XML_SCHEMAP_INVALID_REF_AND_SUBTYPE,
                          "Schemas: element %s have both ref and subtype\n",
                          name, NULL);
            return;
        }
        elemDecl = xmlSchemaGetElem(ctxt->schema, elem->ref, elem->refNs, 0);

        if (elemDecl == NULL) {
            xmlSchemaPErr(ctxt, elem->node, XML_SCHEMAP_UNKNOWN_REF,
                          "Schemas: element %s ref to %s not found\n",
                          name, elem->ref);
            return;
        }
        elem->refDecl = elemDecl;
    } else if (elem->namedType != NULL) {
        xmlSchemaTypePtr typeDecl;

        if (elem->subtypes != NULL) {
            xmlSchemaPErr(ctxt, elem->node, XML_SCHEMAP_TYPE_AND_SUBTYPE,
                          "Schemas: element %s have both type and subtype\n",
                          name, NULL);
            return;
        }
        typeDecl = xmlSchemaGetType(ctxt->schema, elem->namedType,
                                    elem->namedTypeNs);

        if (typeDecl == NULL) {
            xmlSchemaPErr(ctxt, elem->node, XML_SCHEMAP_UNKNOWN_TYPE,
                          "Schemas: element %s type %s not found\n", name,
                          elem->namedType);
            return;
        }
        elem->subtypes = typeDecl;
    }
}

/**
 * xmlSchemaTypeFixup:
 * @typeDecl:  the schema type definition
 * @ctxt:  the schema parser context
 *
 * Fixes the content model of the type.
 */
static void
xmlSchemaTypeFixup(xmlSchemaTypePtr typeDecl,
                   xmlSchemaParserCtxtPtr ctxt, const xmlChar * name)
{
    if (typeDecl == NULL)
        return;
    if (name == NULL)
        name = typeDecl->name;
    if (typeDecl->contentType == XML_SCHEMA_CONTENT_UNKNOWN) {
        switch (typeDecl->type) {
            case XML_SCHEMA_TYPE_SIMPLE_CONTENT:{
                    xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL);
                    if (typeDecl->subtypes != NULL)
                        typeDecl->contentType =
                            typeDecl->subtypes->contentType;
                    break;
                }
            case XML_SCHEMA_TYPE_RESTRICTION:{
                    if (typeDecl->subtypes != NULL)
                        xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL);

                    if (typeDecl->base != NULL) {
                        xmlSchemaTypePtr baseType;

                        baseType =
                            xmlSchemaGetType(ctxt->schema, typeDecl->base,
                                             typeDecl->baseNs);
                        if (baseType == NULL) {
			    xmlSchemaPErr(ctxt, typeDecl->node,
			                  XML_SCHEMAP_UNKNOWN_BASE_TYPE,
				"Schemas: type %s base type %s not found\n",
                                          name, typeDecl->base);
                        }
                        typeDecl->baseType = baseType;
                    }
		    if (typeDecl->subtypes == NULL)
			if (typeDecl->baseType != NULL)
			    typeDecl->contentType =
			             typeDecl->baseType->contentType;
			else 
                            /* 1.1.1 */
                            typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
                    else if ((typeDecl->subtypes->subtypes == NULL) &&
                             ((typeDecl->subtypes->type ==
                               XML_SCHEMA_TYPE_ALL)
                              || (typeDecl->subtypes->type ==
                                  XML_SCHEMA_TYPE_SEQUENCE)))
                        /* 1.1.2 */
                        typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
                    else if ((typeDecl->subtypes->type ==
                              XML_SCHEMA_TYPE_CHOICE)
                             && (typeDecl->subtypes->subtypes == NULL))
                        /* 1.1.3 */
                        typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
                    else {
                        /* 1.2 and 2.X are applied at the other layer */
                        typeDecl->contentType =
                            XML_SCHEMA_CONTENT_ELEMENTS;
                    }
                    break;
                }
            case XML_SCHEMA_TYPE_EXTENSION:{
                    xmlSchemaContentType explicitContentType;
                    xmlSchemaTypePtr base;

                    if (typeDecl->base != NULL) {
                        xmlSchemaTypePtr baseType;

                        baseType =
                            xmlSchemaGetType(ctxt->schema, typeDecl->base,
                                             typeDecl->baseNs);
                        if (baseType == NULL) {
			    xmlSchemaPErr(ctxt, typeDecl->node,
			                  XML_SCHEMAP_UNKNOWN_BASE_TYPE,
				"Schemas: type %s base type %s not found\n",
                                          name, typeDecl->base);
                        }
                        typeDecl->baseType = baseType;
                    }
                    if (typeDecl->subtypes != NULL)
                        xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL);

                    explicitContentType = XML_SCHEMA_CONTENT_ELEMENTS;
                    if (typeDecl->subtypes == NULL)
                        /* 1.1.1 */
                        explicitContentType = XML_SCHEMA_CONTENT_EMPTY;
                    else if ((typeDecl->subtypes->subtypes == NULL) &&
                             ((typeDecl->subtypes->type ==
                               XML_SCHEMA_TYPE_ALL)
                              || (typeDecl->subtypes->type ==
                                  XML_SCHEMA_TYPE_SEQUENCE)))
                        /* 1.1.2 */
                        explicitContentType = XML_SCHEMA_CONTENT_EMPTY;
                    else if ((typeDecl->subtypes->type ==
                              XML_SCHEMA_TYPE_CHOICE)
                             && (typeDecl->subtypes->subtypes == NULL))
                        /* 1.1.3 */
                        explicitContentType = XML_SCHEMA_CONTENT_EMPTY;

                    base = xmlSchemaGetType(ctxt->schema, typeDecl->base,
                                            typeDecl->baseNs);
                    if (base == NULL) {
                        xmlSchemaPErr(ctxt, typeDecl->node,
                                      XML_SCHEMAP_UNKNOWN_BASE_TYPE,
                                      "Schemas: base type %s of type %s not found\n",
                                      typeDecl->base, name);
                        return;
                    }
                    xmlSchemaTypeFixup(base, ctxt, NULL);
                    if (explicitContentType == XML_SCHEMA_CONTENT_EMPTY) {
                        /* 2.1 */
                        typeDecl->contentType = base->contentType;
                    } else if (base->contentType ==
                               XML_SCHEMA_CONTENT_EMPTY) {
                        /* 2.2 imbitable ! */
                        typeDecl->contentType =
                            XML_SCHEMA_CONTENT_ELEMENTS;
                    } else {
                        /* 2.3 imbitable pareil ! */
                        typeDecl->contentType =
                            XML_SCHEMA_CONTENT_ELEMENTS;
                    }
                    break;
                }
            case XML_SCHEMA_TYPE_COMPLEX:{
                    if (typeDecl->subtypes == NULL) {
                        typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;

                        if (typeDecl->flags & XML_SCHEMAS_TYPE_MIXED)
                            typeDecl->contentType =
                                XML_SCHEMA_CONTENT_MIXED;
                    } else {
                        if (typeDecl->flags & XML_SCHEMAS_TYPE_MIXED)
                            typeDecl->contentType =
                                XML_SCHEMA_CONTENT_MIXED;
                        else {
                            xmlSchemaTypeFixup(typeDecl->subtypes, ctxt,
                                               NULL);
                            if (typeDecl->subtypes != NULL)
                                typeDecl->contentType =
                                    typeDecl->subtypes->contentType;
                        }
			if (typeDecl->attributes == NULL)
			    typeDecl->attributes =
			        typeDecl->subtypes->attributes;
                    }
                    break;
                }
            case XML_SCHEMA_TYPE_COMPLEX_CONTENT:{
                    if (typeDecl->subtypes == NULL) {
                        typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
                        if (typeDecl->flags & XML_SCHEMAS_TYPE_MIXED)
                            typeDecl->contentType =
                                XML_SCHEMA_CONTENT_MIXED;
                    } else {
                        if (typeDecl->flags & XML_SCHEMAS_TYPE_MIXED)
                            typeDecl->contentType =
                                XML_SCHEMA_CONTENT_MIXED;
                        else {
                            xmlSchemaTypeFixup(typeDecl->subtypes, ctxt,
                                               NULL);
                            if (typeDecl->subtypes != NULL)
                                typeDecl->contentType =
                                    typeDecl->subtypes->contentType;
                        }
			if (typeDecl->attributes == NULL)
			    typeDecl->attributes =
			        typeDecl->subtypes->attributes;
                    }
                    break;
                }
            case XML_SCHEMA_TYPE_SEQUENCE:
            case XML_SCHEMA_TYPE_GROUP:
            case XML_SCHEMA_TYPE_ALL:
            case XML_SCHEMA_TYPE_CHOICE:
                typeDecl->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
                break;
            case XML_SCHEMA_TYPE_BASIC:
            case XML_SCHEMA_TYPE_ANY:
            case XML_SCHEMA_TYPE_FACET:
            case XML_SCHEMA_TYPE_SIMPLE:
            case XML_SCHEMA_TYPE_UR:
            case XML_SCHEMA_TYPE_ELEMENT:
            case XML_SCHEMA_TYPE_ATTRIBUTE:
            case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
            case XML_SCHEMA_TYPE_NOTATION:
            case XML_SCHEMA_TYPE_LIST:
            case XML_SCHEMA_TYPE_UNION:
            case XML_SCHEMA_FACET_MININCLUSIVE:
            case XML_SCHEMA_FACET_MINEXCLUSIVE:
            case XML_SCHEMA_FACET_MAXINCLUSIVE:
            case XML_SCHEMA_FACET_MAXEXCLUSIVE:
            case XML_SCHEMA_FACET_TOTALDIGITS:
            case XML_SCHEMA_FACET_FRACTIONDIGITS:
            case XML_SCHEMA_FACET_PATTERN:
            case XML_SCHEMA_FACET_ENUMERATION:
            case XML_SCHEMA_FACET_WHITESPACE:
            case XML_SCHEMA_FACET_LENGTH:
            case XML_SCHEMA_FACET_MAXLENGTH:
            case XML_SCHEMA_FACET_MINLENGTH:
                typeDecl->contentType = XML_SCHEMA_CONTENT_SIMPLE;
		if (typeDecl->subtypes != NULL)
		    xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL);
                break;
        }
    }
#ifdef DEBUG_TYPE
    if (typeDecl->node != NULL) {
        xmlGenericError(xmlGenericErrorContext,
                        "Type of %s : %s:%d :", name,
                        typeDecl->node->doc->URL,
                        xmlGetLineNo(typeDecl->node));
    } else {
        xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
    }
    switch (typeDecl->contentType) {
        case XML_SCHEMA_CONTENT_SIMPLE:
            xmlGenericError(xmlGenericErrorContext, "simple\n");
            break;
        case XML_SCHEMA_CONTENT_ELEMENTS:
            xmlGenericError(xmlGenericErrorContext, "elements\n");
            break;
        case XML_SCHEMA_CONTENT_UNKNOWN:
            xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
            break;
        case XML_SCHEMA_CONTENT_EMPTY:
            xmlGenericError(xmlGenericErrorContext, "empty\n");
            break;
        case XML_SCHEMA_CONTENT_MIXED:
            xmlGenericError(xmlGenericErrorContext, "mixed\n");
            break;
        case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
            xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
            break;
        case XML_SCHEMA_CONTENT_BASIC:
            xmlGenericError(xmlGenericErrorContext, "basic\n");
            break;
        default:
            xmlGenericError(xmlGenericErrorContext,
                            "not registered !!!\n");
            break;
    }
#endif
}

/**
 * xmlSchemaCheckFacet:
 * @facet:  the facet
 * @typeDecl:  the schema type definition
 * @ctxt:  the schema parser context or NULL
 * @name: name of the type
 *
 * Checks the default values types, especially for facets 
 *
 * Returns 0 if okay or -1 in cae of error
 */
int
xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
                    xmlSchemaTypePtr typeDecl,
                    xmlSchemaParserCtxtPtr ctxt, const xmlChar * name)
{
    static xmlSchemaTypePtr nonNegativeIntegerType = NULL;
    int ret = 0;

    if (nonNegativeIntegerType == NULL) {
        nonNegativeIntegerType =
            xmlSchemaGetPredefinedType(BAD_CAST "nonNegativeInteger",
                                       xmlSchemaNs);
    }
    switch (facet->type) {
        case XML_SCHEMA_FACET_MININCLUSIVE:
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:{
                /*
                 * Okay we need to validate the value
                 * at that point.
                 */
                xmlSchemaValidCtxtPtr vctxt;

                vctxt = xmlSchemaNewValidCtxt(NULL);
                if (vctxt == NULL)
                    break;
                xmlSchemaValidateSimpleValue(vctxt, typeDecl,
                                             facet->value);
                facet->val = vctxt->value;
                vctxt->value = NULL;
                if (facet->val == NULL) {
                    /* error code */
                    if (ctxt != NULL) {
                        xmlSchemaPErr(ctxt, facet->node,
                                      XML_SCHEMAP_INVALID_FACET,
                                      "Schemas: type %s facet value %s invalid\n",
                                      name, facet->value);
                    }
                    ret = -1;
                }
                xmlSchemaFreeValidCtxt(vctxt);
                break;
            }
        case XML_SCHEMA_FACET_ENUMERATION:{
                /*
                 * Okay we need to validate the value
                 * at that point.
                 */
                xmlSchemaValidCtxtPtr vctxt;
                int tmp;

                vctxt = xmlSchemaNewValidCtxt(NULL);
                if (vctxt == NULL)
                    break;
                tmp = xmlSchemaValidateSimpleValue(vctxt, typeDecl,
                                                   facet->value);
                if (tmp != 0) {
                    if (ctxt != NULL) {
                        xmlSchemaPErr(ctxt, facet->node,
                                      XML_SCHEMAP_INVALID_ENUM,
                                      "Schemas: type %s enumeration value %s invalid\n",
                                      name, facet->value);
                    }
                    ret = -1;
                }
                xmlSchemaFreeValidCtxt(vctxt);
                break;
            }
        case XML_SCHEMA_FACET_PATTERN:
            facet->regexp = xmlRegexpCompile(facet->value);
            if (facet->regexp == NULL) {
		xmlSchemaPErr(ctxt, typeDecl->node,
			      XML_SCHEMAP_REGEXP_INVALID,
                              "Schemas: type %s facet regexp %s invalid\n",
                              name, facet->value);
                ret = -1;
            }
            break;
        case XML_SCHEMA_FACET_TOTALDIGITS:
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
        case XML_SCHEMA_FACET_LENGTH:
        case XML_SCHEMA_FACET_MAXLENGTH:
        case XML_SCHEMA_FACET_MINLENGTH:{
                int tmp;

                tmp =
                    xmlSchemaValidatePredefinedType(nonNegativeIntegerType,
                                                    facet->value,
                                                    &facet->val);
                if (tmp != 0) {
                    /* error code */
                    if (ctxt != NULL) {
                        xmlSchemaPErr(ctxt, facet->node,
                                      XML_SCHEMAP_INVALID_FACET_VALUE,
                                      "Schemas: type %s facet value %s invalid\n",
                                      name, facet->value);
                    }
                    ret = -1;
                }
                break;
            }
        case XML_SCHEMA_FACET_WHITESPACE:{
                if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
                    facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
                } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
                    facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
                } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
                    facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
                } else {
                    if (ctxt != NULL) {
                        xmlSchemaPErr(ctxt, facet->node,
                                      XML_SCHEMAP_INVALID_WHITE_SPACE,
                                      "Schemas: type %s whiteSpace value %s invalid\n",
                                      name, facet->value);
                    }
                    ret = -1;
                }
            }
        default:
            break;
    }
    return (ret);
}

/**
 * xmlSchemaCheckDefaults:
 * @typeDecl:  the schema type definition
 * @ctxt:  the schema parser context
 *
 * Checks the default values types, especially for facets 
 */
static void
xmlSchemaCheckDefaults(xmlSchemaTypePtr typeDecl,
                       xmlSchemaParserCtxtPtr ctxt, const xmlChar * name)
{
    if (name == NULL)
        name = typeDecl->name;
    if (typeDecl->type == XML_SCHEMA_TYPE_RESTRICTION) {
        if (typeDecl->facets != NULL) {
            xmlSchemaFacetPtr facet = typeDecl->facets;

            while (facet != NULL) {
                xmlSchemaCheckFacet(facet, typeDecl, ctxt, name);
                facet = facet->next;
            }
        }
    }
}

/**
 * xmlSchemaAttrGrpFixup:
 * @attrgrpDecl:  the schema attribute definition
 * @ctxt:  the schema parser context
 * @name:  the attribute name
 *
 * Fixes finish doing the computations on the attributes definitions
 */
static void
xmlSchemaAttrGrpFixup(xmlSchemaAttributeGroupPtr attrgrpDecl,
                      xmlSchemaParserCtxtPtr ctxt, const xmlChar * name)
{
    if (name == NULL)
        name = attrgrpDecl->name;
    if (attrgrpDecl->attributes != NULL)
        return;
    if (attrgrpDecl->ref != NULL) {
        xmlSchemaAttributeGroupPtr ref;

        ref = xmlHashLookup2(ctxt->schema->attrgrpDecl, attrgrpDecl->ref,
                             attrgrpDecl->refNs);
        if (ref == NULL) {
            xmlSchemaPErr(ctxt, attrgrpDecl->node,
                          XML_SCHEMAP_UNKNOWN_ATTRIBUTE_GROUP,
                          "Schemas: attribute group %s reference %s not found\n",
                          name, attrgrpDecl->ref);
            return;
        }
        xmlSchemaAttrGrpFixup(ref, ctxt, NULL);
        attrgrpDecl->attributes = ref->attributes;
    } else {
        xmlSchemaPErr(ctxt, attrgrpDecl->node, XML_SCHEMAP_NOATTR_NOREF,
                      "Schemas: attribute %s has no attributes nor reference\n",
                      name, NULL);
    }
}

/**
 * xmlSchemaAttrFixup:
 * @attrDecl:  the schema attribute definition
 * @ctxt:  the schema parser context
 * @name:  the attribute name
 *
 * Fixes finish doing the computations on the attributes definitions
 */
static void
xmlSchemaAttrFixup(xmlSchemaAttributePtr attrDecl,
                   xmlSchemaParserCtxtPtr ctxt, const xmlChar * name)
{
    if (name == NULL)
        name = attrDecl->name;
    if (attrDecl->subtypes != NULL)
        return;
    if (attrDecl->typeName != NULL) {
        xmlSchemaTypePtr type;

        type = xmlSchemaGetType(ctxt->schema, attrDecl->typeName,
                                attrDecl->typeNs);
        if (type == NULL) {
            xmlSchemaPErr(ctxt, attrDecl->node, XML_SCHEMAP_UNKNOWN_TYPE,
                          "Schemas: attribute %s type %s not found\n",
                          name, attrDecl->typeName);
        }
        attrDecl->subtypes = type;
    } else if (attrDecl->ref != NULL) {
        xmlSchemaAttributePtr ref;

        ref = xmlHashLookup2(ctxt->schema->attrDecl, attrDecl->ref,
                             attrDecl->refNs);
        if (ref == NULL) {
            xmlSchemaPErr(ctxt, attrDecl->node, XML_SCHEMAP_UNKNOWN_REF,
                          "Schemas: attribute %s reference %s not found\n",
                          name, attrDecl->ref);
            return;
        }
        xmlSchemaAttrFixup(ref, ctxt, NULL);
        attrDecl->subtypes = ref->subtypes;
    } else {
        xmlSchemaPErr(ctxt, attrDecl->node, XML_SCHEMAP_NOTYPE_NOREF,
                      "Schemas: attribute %s has no type nor reference\n",
                      name, NULL);
    }
}

/**
 * xmlSchemaParse:
 * @ctxt:  a schema validation context
 *
 * parse a schema definition resource and build an internal
 * XML Shema struture which can be used to validate instances.
 * *WARNING* this interface is highly subject to change
 *
 * Returns the internal XML Schema structure built from the resource or
 *         NULL in case of error
 */
xmlSchemaPtr
xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
{
    xmlSchemaPtr ret = NULL;
    xmlDocPtr doc;
    xmlNodePtr root;
    int nberrors;
    int preserve = 0;

    xmlSchemaInitTypes();

    if (ctxt == NULL)
        return (NULL);

    nberrors = ctxt->nberrors;
    ctxt->nberrors = 0;
    ctxt->counter = 0;
    ctxt->container = NULL;

    /*
     * First step is to parse the input document into an DOM/Infoset
     */
    if (ctxt->URL != NULL) {
        doc = xmlReadFile((const char *) ctxt->URL, NULL, 
	                  SCHEMAS_PARSE_OPTIONS);
        if (doc == NULL) {
	    xmlSchemaPErr(ctxt, NULL,
			  XML_SCHEMAP_FAILED_LOAD,
                          "xmlSchemaParse: could not load %s\n",
                          ctxt->URL, NULL);
            return (NULL);
        }
    } else if (ctxt->buffer != NULL) {
        doc = xmlReadMemory(ctxt->buffer, ctxt->size, NULL, NULL,
	                    SCHEMAS_PARSE_OPTIONS);
        if (doc == NULL) {
	    xmlSchemaPErr(ctxt, NULL,
			  XML_SCHEMAP_FAILED_PARSE,
                          "xmlSchemaParse: could not parse\n",
                          NULL, NULL);
            return (NULL);
        }
        doc->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
        ctxt->URL = xmlDictLookup(ctxt->dict, BAD_CAST "in_memory_buffer", -1);
    } else if (ctxt->doc != NULL) {
        doc = ctxt->doc;
	preserve = 1;
    } else {
	xmlSchemaPErr(ctxt, NULL,
		      XML_SCHEMAP_NOTHING_TO_PARSE,
		      "xmlSchemaParse: could not parse\n",
		      NULL, NULL);
        return (NULL);
    }

    /*
     * Then extract the root and Schema parse it
     */
    root = xmlDocGetRootElement(doc);
    if (root == NULL) {
	xmlSchemaPErr(ctxt, (xmlNodePtr) doc,
		      XML_SCHEMAP_NOROOT,
		      "schemas has no root", NULL, NULL);
	if (!preserve) {
	    xmlFreeDoc(doc);
	}
        return (NULL);
    }

    /*
     * Remove all the blank text nodes
     */
    xmlSchemaCleanupDoc(ctxt, root);

    /*
     * Then do the parsing for good
     */
    ret = xmlSchemaParseSchema(ctxt, root);
    if (ret == NULL) {
        if (!preserve) {
	    xmlFreeDoc(doc);
	}
        return (NULL);
    }
    ret->doc = doc;
    ret->preserve = preserve;

    /*
     * Then fix all the references.
     */
    ctxt->schema = ret;
    xmlHashScanFull(ret->elemDecl,
                    (xmlHashScannerFull) xmlSchemaRefFixupCallback, ctxt);

    /*
     * Then fixup all attributes declarations
     */
    xmlHashScan(ret->attrDecl, (xmlHashScanner) xmlSchemaAttrFixup, ctxt);

    /*
     * Then fixup all attributes group declarations
     */
    xmlHashScan(ret->attrgrpDecl, (xmlHashScanner) xmlSchemaAttrGrpFixup,
                ctxt);

    /*
     * Then fixup all types properties
     */
    xmlHashScan(ret->typeDecl, (xmlHashScanner) xmlSchemaTypeFixup, ctxt);

    /*
     * Then build the content model for all elements
     */
    xmlHashScan(ret->elemDecl,
                (xmlHashScanner) xmlSchemaBuildContentModel, ctxt);

    /*
     * Then check the defaults part of the type like facets values
     */
    xmlHashScan(ret->typeDecl, (xmlHashScanner) xmlSchemaCheckDefaults,
                ctxt);

    if (ctxt->nberrors != 0) {
        xmlSchemaFree(ret);
        ret = NULL;
    }
    return (ret);
}

/**
 * xmlSchemaSetParserErrors:
 * @ctxt:  a schema validation context
 * @err:  the error callback
 * @warn:  the warning callback
 * @ctx:  contextual data for the callbacks
 *
 * Set the callback functions used to handle errors for a validation context
 */
void
xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
                         xmlSchemaValidityErrorFunc err,
                         xmlSchemaValidityWarningFunc warn, void *ctx)
{
    if (ctxt == NULL)
        return;
    ctxt->error = err;
    ctxt->warning = warn;
    ctxt->userData = ctx;
}

/**
 * xmlSchemaFacetTypeToString:
 * @type:  the facet type
 *
 * Convert the xmlSchemaTypeType to a char string.
 *
 * Returns the char string representation of the facet type if the
 *     type is a facet and an "Internal Error" string otherwise.
 */
static const char *
xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
{
    switch (type) {
        case XML_SCHEMA_FACET_PATTERN:
            return ("pattern");
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
            return ("maxExclusive");
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
            return ("maxInclusive");
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
            return ("minExclusive");
        case XML_SCHEMA_FACET_MININCLUSIVE:
            return ("minInclusive");
        case XML_SCHEMA_FACET_WHITESPACE:
            return ("whiteSpace");
        case XML_SCHEMA_FACET_ENUMERATION:
            return ("enumeration");
        case XML_SCHEMA_FACET_LENGTH:
            return ("length");
        case XML_SCHEMA_FACET_MAXLENGTH:
            return ("maxLength");
        case XML_SCHEMA_FACET_MINLENGTH:
            return ("minLength");
        case XML_SCHEMA_FACET_TOTALDIGITS:
            return ("totalDigits");
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
            return ("fractionDigits");
        default:
            break;
    }
    return ("Internal Error");
}

/**
 * xmlSchemaValidateFacets:
 * @ctxt:  a schema validation context
 * @base:  the base type
 * @facets:  the list of facets to check
 * @value:  the lexical repr of the value to validate
 * @val:  the precomputed value
 *
 * Check a value against all facet conditions
 *
 * Returns 0 if the element is schemas valid, a positive error code
 *     number otherwise and -1 in case of internal or API error.
 */
static int
xmlSchemaValidateFacets(xmlSchemaValidCtxtPtr ctxt,
                        xmlSchemaTypePtr base,
                        xmlSchemaFacetPtr facets, const xmlChar * value)
{
    int ret = 0;
    int tmp = 0;
    xmlSchemaTypeType type;
    xmlSchemaFacetPtr facet = facets;

    while (facet != NULL) {
        type = facet->type;
        if (type == XML_SCHEMA_FACET_ENUMERATION) {
            tmp = 1;

            while (facet != NULL) {
                tmp =
                    xmlSchemaValidateFacet(base, facet, value,
                                           ctxt->value);
                if (tmp == 0) {
                    return 0;
                }
                facet = facet->next;
            }
        } else
            tmp = xmlSchemaValidateFacet(base, facet, value, ctxt->value);

        if (tmp != 0) {
            ret = tmp;
            xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_FACET, "Failed to validate type with facet %s\n", (const xmlChar *) xmlSchemaFacetTypeToString(type), NULL);
        }
        if (facet != NULL)
            facet = facet->next;
    }
    return (ret);
}

/************************************************************************
 * 									*
 * 			Simple type validation				*
 * 									*
 ************************************************************************/

/**
 * xmlSchemaValidateSimpleValue:
 * @ctxt:  a schema validation context
 * @type:  the type declaration
 * @value:  the value to validate
 *
 * Validate a value against a simple type
 *
 * Returns 0 if the value is valid, a positive error code
 *     number otherwise and -1 in case of internal or API error.
 */
static int
xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
                             xmlSchemaTypePtr type, const xmlChar * value)
{
    int ret = 0;

    /*
     * First normalize the value accordingly to Schema Datatype
     * 4.3.6 whiteSpace definition of the whiteSpace facet of type
     */
    /*
     * Then check the normalized value against the lexical space of the
     * type.
     */
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
        if (ctxt->value != NULL) {
            xmlSchemaFreeValue(ctxt->value);
            ctxt->value = NULL;
        }
        ret = xmlSchemaValPredefTypeNode(type, value, &(ctxt->value),
                                         ctxt->cur);
        if (ret != 0) {
            xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_VALUE, "Failed to validate basic type %s\n", type->name, NULL);
        }
    } else if (type->type == XML_SCHEMA_TYPE_RESTRICTION) {
        xmlSchemaTypePtr base;
        xmlSchemaFacetPtr facet;

        base = type->baseType;
        if (base != NULL) {
            ret = xmlSchemaValidateSimpleValue(ctxt, base, value);
        } else if (type->subtypes != NULL) {
	    TODO
        }

        /*
         * Do not validate facets or attributes when working on
	 * building the Schemas
         */
        if (ctxt->schema != NULL) {
            if (ret == 0) {
                facet = type->facets;
                ret = xmlSchemaValidateFacets(ctxt, base, facet, value);
            }
        }
    } else if (type->type == XML_SCHEMA_TYPE_SIMPLE) {
        xmlSchemaTypePtr base;

        base = type->subtypes;
        if (base != NULL) {
            ret = xmlSchemaValidateSimpleValue(ctxt, base, value);
        } else {
        TODO}
    } else if (type->type == XML_SCHEMA_TYPE_LIST) {
        xmlSchemaTypePtr base;
        const xmlChar *cur, *end;
	xmlChar *tmp;
        int ret2;

        base = type->subtypes;
        if (base == NULL) {
	    xmlSchemaVErr(ctxt, type->node, XML_SCHEMAS_ERR_INTERNAL,
			"Internal: List type %s has no base type\n",
			type->name, NULL);
            return (-1);
        }
        cur = value;
        do {
            while (IS_BLANK_CH(*cur))
                cur++;
            end = cur;
            while ((*end != 0) && (!(IS_BLANK_CH(*end))))
                end++;
            if (end == cur)
                break;
            tmp = xmlStrndup(cur, end - cur);
            ret2 = xmlSchemaValidateSimpleValue(ctxt, base, tmp);
	    xmlFree(tmp);
            if (ret2 != 0)
                ret = 1;
            cur = end;
        } while (*cur != 0);
    } else {
        TODO
    }
    return (ret);
}

/************************************************************************
 * 									*
 * 			DOM Validation code				*
 * 									*
 ************************************************************************/

static int xmlSchemaValidateContent(xmlSchemaValidCtxtPtr ctxt,
                                    xmlNodePtr node);
static int xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt,
                                       xmlNodePtr elem,
                                       xmlSchemaAttributePtr attributes);
static int xmlSchemaValidateType(xmlSchemaValidCtxtPtr ctxt,
                                 xmlNodePtr elem,
                                 xmlSchemaElementPtr elemDecl,
                                 xmlSchemaTypePtr type);

/**
 * xmlSchemaRegisterAttributes:
 * @ctxt:  a schema validation context
 * @attrs:  a list of attributes
 *
 * Register the list of attributes as the set to be validated on that element
 *
 * Returns -1 in case of error, 0 otherwise
 */
static int
xmlSchemaRegisterAttributes(xmlSchemaValidCtxtPtr ctxt, xmlAttrPtr attrs)
{
    while (attrs != NULL) {
        if ((attrs->ns != NULL) &&
            (xmlStrEqual(attrs->ns->href, xmlSchemaInstanceNs))) {
            attrs = attrs->next;
            continue;
        }
        if (ctxt->attrNr >= ctxt->attrMax) {
            xmlSchemaAttrStatePtr tmp;

            ctxt->attrMax *= 2;
            tmp = (xmlSchemaAttrStatePtr)
                xmlRealloc(ctxt->attr, ctxt->attrMax *
                           sizeof(xmlSchemaAttrState));
            if (tmp == NULL) {
                xmlSchemaVErrMemory(ctxt, "registering attributes", NULL);
                ctxt->attrMax /= 2;
                return (-1);
            }
            ctxt->attr = tmp;
        }
        ctxt->attr[ctxt->attrNr].attr = attrs;
        ctxt->attr[ctxt->attrNr].state = XML_SCHEMAS_ATTR_UNKNOWN;
        ctxt->attrNr++;
        attrs = attrs->next;
    }
    return (0);
}

/**
 * xmlSchemaCheckAttributes:
 * @ctxt:  a schema validation context
 * @node:  the node carrying it.
 *
 * Check that the registered set of attributes on the current node
 * has been properly validated.
 *
 * Returns 0 if validity constraints are met, 1 otherwise.
 */
static int
xmlSchemaCheckAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node)
{
    int ret = 0;
    int i;

    for (i = ctxt->attrBase; i < ctxt->attrNr; i++) {
        if (ctxt->attr[i].attr == NULL)
            break;
        if (ctxt->attr[i].state == XML_SCHEMAS_ATTR_UNKNOWN) {
            ret = 1;
            xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_ATTRUNKNOWN, "Attribute %s on %s is unknown\n", ctxt->attr[i].attr->name, node->name);
        }
    }
    return (ret);
}

/**
 * xmlSchemaValidateSimpleContent:
 * @ctxt:  a schema validation context
 * @elem:  an element
 * @type:  the type declaration
 *
 * Validate the content of an element expected to be a simple type
 *
 * Returns 0 if the element is schemas valid, a positive error code
 *     number otherwise and -1 in case of internal or API error.
 */
static int
xmlSchemaValidateSimpleContent(xmlSchemaValidCtxtPtr ctxt,
                               xmlNodePtr node ATTRIBUTE_UNUSED)
{
    xmlNodePtr child;
    xmlSchemaTypePtr type, base;
    xmlChar *value;
    int ret = 0;

    child = ctxt->node;
    type = ctxt->type;

    /*
     * Validation Rule: Element Locally Valid (Type): 3.1.3
     */
    value = xmlNodeGetContent(child);
    /* xmlSchemaValidateSimpleValue(ctxt, type, value); */
    switch (type->type) {
        case XML_SCHEMA_TYPE_RESTRICTION:{
                xmlSchemaFacetPtr facet;

                base = type->baseType;
                if (base != NULL) {
                    ret = xmlSchemaValidateSimpleValue(ctxt, base, value);
                } else {
                TODO}
                if (ret == 0) {
                    facet = type->facets;
                    ret =
                        xmlSchemaValidateFacets(ctxt, base, facet, value);
                }
		if ((ret == 0) && (type->attributes != NULL)) {
		    ret = xmlSchemaValidateAttributes(ctxt, node,
		                                      type->attributes);
		}
                break;
            }
        case XML_SCHEMA_TYPE_EXTENSION:{
	        TODO
                break;
            }
        default:
	    TODO
    }
    if (value != NULL)
        xmlFree(value);

    return (ret);
}

/**
 * xmlSchemaValidateCheckNodeList
 * @nodelist: the list of nodes
 *
 * Check the node list is only made of text nodes and entities pointing
 * to text nodes
 *
 * Returns 1 if true, 0 if false and -1 in case of error
 */
static int
xmlSchemaValidateCheckNodeList(xmlNodePtr nodelist)
{
    while (nodelist != NULL) {
        if (nodelist->type == XML_ENTITY_REF_NODE) {
            TODO                /* implement recursion in the entity content */
        }
        if ((nodelist->type != XML_TEXT_NODE) &&
            (nodelist->type != XML_COMMENT_NODE) &&
            (nodelist->type != XML_PI_NODE) &&
            (nodelist->type != XML_PI_NODE)) {
            return (0);
        }
        nodelist = nodelist->next;
    }
    return (1);
}

/**
 * xmlSchemaSkipIgnored:
 * @ctxt:  a schema validation context
 * @type:  the current type context
 * @node:  the top node.
 *
 * Skip ignorable nodes in that context
 *
 * Returns the new sibling
 *     number otherwise and -1 in case of internal or API error.
 */
static xmlNodePtr
xmlSchemaSkipIgnored(xmlSchemaValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
                     xmlSchemaTypePtr type, xmlNodePtr node)
{
    int mixed = 0;

    /*
     * TODO complete and handle entities
     */
    mixed = ((type->contentType == XML_SCHEMA_CONTENT_MIXED) ||
             (type->contentType == XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS));
    while ((node != NULL) &&
           ((node->type == XML_COMMENT_NODE) ||
            ((mixed == 1) && (node->type == XML_TEXT_NODE)) ||
            (((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) &&
              (node->type == XML_TEXT_NODE) && (IS_BLANK_NODE(node)))))) {
        node = node->next;
    }
    return (node);
}

/**
 * xmlSchemaValidateCallback:
 * @ctxt:  a schema validation context
 * @name:  the name of the element detected (might be NULL)
 * @type:  the type
 *
 * A transition has been made in the automata associated to an element
 * content model
 */
static void
xmlSchemaValidateCallback(xmlSchemaValidCtxtPtr ctxt,
                          const xmlChar * name ATTRIBUTE_UNUSED,
                          xmlSchemaTypePtr type, xmlNodePtr node)
{
    xmlSchemaTypePtr oldtype = ctxt->type;
    xmlNodePtr oldnode = ctxt->node;

#ifdef DEBUG_CONTENT
    xmlGenericError(xmlGenericErrorContext,
                    "xmlSchemaValidateCallback: %s, %s, %s\n",
                    name, type->name, node->name);
#endif
    ctxt->type = type;
    ctxt->node = node;
    xmlSchemaValidateContent(ctxt, node);
    ctxt->type = oldtype;
    ctxt->node = oldnode;
}


#if 0

/**
 * xmlSchemaValidateSimpleRestrictionType:
 * @ctxt:  a schema validation context
 * @node:  the top node.
 *
 * Validate the content of a restriction type.
 *
 * Returns 0 if the element is schemas valid, a positive error code
 *     number otherwise and -1 in case of internal or API error.
 */
static int
xmlSchemaValidateSimpleRestrictionType(xmlSchemaValidCtxtPtr ctxt,
                                       xmlNodePtr node)
{
    xmlNodePtr child;
    xmlSchemaTypePtr type;
    int ret;

    child = ctxt->node;
    type = ctxt->type;

    if ((ctxt == NULL) || (type == NULL)) {
        xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL, "Internal error: xmlSchemaValidateSimpleRestrictionType %s\n", node->name, NULL);
        return (-1);
    }
    /*
     * Only text and text based entities references shall be found there
     */
    ret = xmlSchemaValidateCheckNodeList(child);
    if (ret < 0) {
        xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL, "Internal error: xmlSchemaValidateSimpleType %s content\n", node->name, NULL);
        return (-1);
    } else if (ret == 0) {
        xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_NOTSIMPLE, "Element %s content is not a simple type\n", node->name, NULL);
        return (-1);
    }
    ctxt->type = type->subtypes;
    xmlSchemaValidateContent(ctxt, node);
    ctxt->type = type;
    return (ret);
}
#endif

/**
 * xmlSchemaValidateSimpleType:
 * @ctxt:  a schema validation context
 * @node:  the top node.
 *
 * Validate the content of an simple type.
 *
 * Returns 0 if the element is schemas valid, a positive error code
 *     number otherwise and -1 in case of internal or API error.
 */
static int
xmlSchemaValidateSimpleType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node)
{
    xmlNodePtr child;
    xmlSchemaTypePtr type;
    xmlAttrPtr attr;
    int ret;

    child = ctxt->node;
    type = ctxt->type;

    if ((ctxt == NULL) || (type == NULL)) {
        xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL, "Internal error: xmlSchemaValidateSimpleType %s\n", node->name, NULL);
        return (-1);
    }
    /*
     * Only text and text based entities references shall be found there
     */
    ret = xmlSchemaValidateCheckNodeList(child);
    if (ret < 0) {
        xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL, "Internal error: xmlSchemaValidateSimpleType %s content\n", node->name, NULL);
        return (-1);
    } else if (ret == 0) {
        xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_NOTSIMPLE, "Element %s content is not a simple type\n", node->name, NULL);
        return (-1);
    }
    /*
     * Validation Rule: Element Locally Valid (Type): 3.1.1
     */
    attr = node->properties;
    while (attr != NULL) {
        if ((attr->ns == NULL) ||
            (!xmlStrEqual(attr->ns->href, xmlSchemaInstanceNs)) ||
            ((!xmlStrEqual(attr->name, BAD_CAST "type")) &&
             (!xmlStrEqual(attr->name, BAD_CAST "nil")) &&
             (!xmlStrEqual(attr->name, BAD_CAST "schemasLocation")) &&
             (!xmlStrEqual
              (attr->name, BAD_CAST "noNamespaceSchemaLocation")))) {
            xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INVALIDATTR, "Element %s: attribute %s should not be present\n", node->name, attr->name);
            return (ctxt->err);
        }
    }

    ctxt->type = type->subtypes;
    ret = xmlSchemaValidateSimpleContent(ctxt, node);
    ctxt->type = type;
    return (ret);
}

/**
 * xmlSchemaValidateElementType:
 * @ctxt:  a schema validation context
 * @node:  the top node.
 *
 * Validate the content of an element type.
 * Validation Rule: Element Locally Valid (Complex Type)
 *
 * Returns 0 if the element is schemas valid, a positive error code
 *     number otherwise and -1 in case of internal or API error.
 */
static int
xmlSchemaValidateElementType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node)
{
    xmlNodePtr child;
    xmlSchemaTypePtr type;
    xmlRegExecCtxtPtr oldregexp;        /* cont model of the parent */
    xmlSchemaElementPtr decl;
    int ret, attrBase;

    oldregexp = ctxt->regexp;

    child = ctxt->node;
    type = ctxt->type;

    if ((ctxt == NULL) || (type == NULL)) {
        xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL, "Internal error: xmlSchemaValidateElementType\n", node->name, NULL);
        return (-1);
    }
    if (child == NULL) {
        if (type->minOccurs > 0) {
            xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_MISSING, "Element %s: missing child %s\n", node->name, type->name);
        }
        return (ctxt->err);
    }

    /*
     * Verify the element matches
     */
    if (!xmlStrEqual(child->name, type->name)) {
        xmlSchemaVErr3(ctxt, node, XML_SCHEMAS_ERR_WRONGELEM, "Element %s: missing child %s found %s\n", node->name, type->name, child->name);
        return (ctxt->err);
    }
    /*
     * Verify the attributes
     */
    attrBase = ctxt->attrBase;
    ctxt->attrBase = ctxt->attrNr;
    xmlSchemaRegisterAttributes(ctxt, child->properties);
    xmlSchemaValidateAttributes(ctxt, child, type->attributes);
    /*
     * Verify the element content recursively
     */
    decl = (xmlSchemaElementPtr) type;
    oldregexp = ctxt->regexp;
    if (decl->contModel != NULL) {
        ctxt->regexp = xmlRegNewExecCtxt(decl->contModel,
                                         (xmlRegExecCallbacks)
                                         xmlSchemaValidateCallback, ctxt);
#ifdef DEBUG_AUTOMATA
        xmlGenericError(xmlGenericErrorContext, "====> %s\n", node->name);
#endif
    }
    xmlSchemaValidateType(ctxt, child, (xmlSchemaElementPtr) type,
                          type->subtypes);

    if (decl->contModel != NULL) {
        ret = xmlRegExecPushString(ctxt->regexp, NULL, NULL);
#ifdef DEBUG_AUTOMATA
        xmlGenericError(xmlGenericErrorContext,
                        "====> %s : %d\n", node->name, ret);
#endif
        if (ret == 0) {
            xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_ELEMCONT, "Element %s content check failed\n", node->name, NULL);
        } else if (ret < 0) {
            xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_ELEMCONT, "Element %s content check failure\n", node->name, NULL);
#ifdef DEBUG_CONTENT
        } else {
            xmlGenericError(xmlGenericErrorContext,
                            "Element %s content check succeeded\n",
                            node->name);

#endif
        }
        xmlRegFreeExecCtxt(ctxt->regexp);
    }
    /*
     * Verify that all attributes were Schemas-validated
     */
    xmlSchemaCheckAttributes(ctxt, node);
    ctxt->attrNr = ctxt->attrBase;
    ctxt->attrBase = attrBase;

    ctxt->regexp = oldregexp;

    ctxt->node = child;
    ctxt->type = type;
    return (ctxt->err);
}

/**
 * xmlSchemaValidateBasicType:
 * @ctxt:  a schema validation context
 * @node:  the top node.
 *
 * Validate the content of an element expected to be a basic type type
 *
 * Returns 0 if the element is schemas valid, a positive error code
 *     number otherwise and -1 in case of internal or API error.
 */
static int
xmlSchemaValidateBasicType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node)
{
    int ret;
    xmlNodePtr child, cur;
    xmlSchemaTypePtr type;
    xmlChar *value;             /* lexical representation */

    child = ctxt->node;
    type = ctxt->type;

    if ((ctxt == NULL) || (type == NULL)) {
        xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL, "Internal error: xmlSchemaValidateBasicType\n", node->name, NULL);
        return (-1);
    }
    /*
     * First check the content model of the node.
     */
    cur = child;
    while (cur != NULL) {
        switch (cur->type) {
            case XML_TEXT_NODE:
            case XML_CDATA_SECTION_NODE:
            case XML_PI_NODE:
            case XML_COMMENT_NODE:
            case XML_XINCLUDE_START:
            case XML_XINCLUDE_END:
                break;
            case XML_ENTITY_REF_NODE:
            case XML_ENTITY_NODE:
                TODO break;
            case XML_ELEMENT_NODE:
                xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INVALIDELEM, "Element %s: child %s should not be present\n", node->name, cur->name);
                return (ctxt->err);
            case XML_ATTRIBUTE_NODE:
            case XML_DOCUMENT_NODE:
            case XML_DOCUMENT_TYPE_NODE:
            case XML_DOCUMENT_FRAG_NODE:
            case XML_NOTATION_NODE:
            case XML_HTML_DOCUMENT_NODE:
            case XML_DTD_NODE:
            case XML_ELEMENT_DECL:
            case XML_ATTRIBUTE_DECL:
            case XML_ENTITY_DECL:
            case XML_NAMESPACE_DECL:
#ifdef LIBXML_DOCB_ENABLED
            case XML_DOCB_DOCUMENT_NODE:
#endif
                xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INVALIDELEM, "Element %s: node type of node unexpected here\n", node->name, NULL);
                return (ctxt->err);
        }
        cur = cur->next;
    }
    if (child == NULL)
        value = NULL;
    else
        value = xmlNodeGetContent(child->parent);

    if (ctxt->value != NULL) {
        xmlSchemaFreeValue(ctxt->value);
        ctxt->value = NULL;
    }
    ret = xmlSchemaValidatePredefinedType(type, value, &(ctxt->value));
    if (value != NULL)
        xmlFree(value);
    if (ret != 0) {
        xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_VALUE, "Element %s: failed to validate basic type %s\n", node->name, type->name);
    }
    return (ret);
}

/**
 * xmlSchemaValidateComplexType:
 * @ctxt:  a schema validation context
 * @node:  the top node.
 *
 * Validate the content of an element expected to be a complex type type
 * xmlschema-1.html#cvc-complex-type
 * Validation Rule: Element Locally Valid (Complex Type)
 *
 * Returns 0 if the element is schemas valid, a positive error code
 *     number otherwise and -1 in case of internal or API error.
 */
static int
xmlSchemaValidateComplexType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node)
{
    xmlNodePtr child;
    xmlSchemaTypePtr type, subtype;
    int ret;

    child = ctxt->node;
    type = ctxt->type;
    ctxt->cur = node;

    switch (type->contentType) {
        case XML_SCHEMA_CONTENT_EMPTY:
	    if (type->baseType != NULL) {
	    } else if (child != NULL) {
		xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_NOTEMPTY, "Element %s is supposed to be empty\n", node->name, NULL);
            }
            if (type->attributes != NULL) {
                xmlSchemaValidateAttributes(ctxt, node, type->attributes);
            }
            subtype = type->subtypes;
            while (subtype != NULL) {
                ctxt->type = subtype;
                xmlSchemaValidateComplexType(ctxt, node);
                subtype = subtype->next;
            }
            break;
        case XML_SCHEMA_CONTENT_ELEMENTS:
        case XML_SCHEMA_CONTENT_MIXED:
        case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
            /*
             * Skip ignorable nodes in that context
             */
            child = xmlSchemaSkipIgnored(ctxt, type, child);
            while (child != NULL) {
                if (child->type == XML_ELEMENT_NODE) {
                    ret = xmlRegExecPushString(ctxt->regexp,
                                               child->name, child);
#ifdef DEBUG_AUTOMATA
                    if (ret < 0)
                        xmlGenericError(xmlGenericErrorContext,
                                        "  --> %s Error\n", child->name);
                    else
                        xmlGenericError(xmlGenericErrorContext,
                                        "  --> %s\n", child->name);
#endif
                }
                child = child->next;
                /*
                 * Skip ignorable nodes in that context
                 */
                child = xmlSchemaSkipIgnored(ctxt, type, child);
            }
            if (type->attributes != NULL) {
                xmlSchemaValidateAttributes(ctxt, node, type->attributes);
            }
            break;
        case XML_SCHEMA_CONTENT_BASIC:{
                if (type->subtypes != NULL) {
                    ctxt->type = type->subtypes;
                    xmlSchemaValidateComplexType(ctxt, node);
                }
                if (type->baseType != NULL) {
                    ctxt->type = type->baseType;
                    xmlSchemaValidateBasicType(ctxt, node);
                }
                if (type->attributes != NULL) {
                    xmlSchemaValidateAttributes(ctxt, node,
                                                type->attributes);
                }
                ctxt->type = type;
                break;
            }
        case XML_SCHEMA_CONTENT_SIMPLE:{
                if (type->subtypes != NULL) {
                    ctxt->type = type->subtypes;
                    xmlSchemaValidateComplexType(ctxt, node);
                }
                if (type->baseType != NULL) {
                    ctxt->type = type->baseType;
                    xmlSchemaValidateComplexType(ctxt, node);
                }
                if (type->attributes != NULL) {
                    xmlSchemaValidateAttributes(ctxt, node,
                                                type->attributes);
                }
                ctxt->type = type;
                break;
	}
        default:
            TODO xmlGenericError(xmlGenericErrorContext,
                                 "unimplemented content type %d\n",
                                 type->contentType);
    }
    return (ctxt->err);
}

/**
 * xmlSchemaValidateContent:
 * @ctxt:  a schema validation context
 * @elem:  an element
 * @type:  the type declaration
 *
 * Validate the content of an element against the type.
 *
 * Returns 0 if the element is schemas valid, a positive error code
 *     number otherwise and -1 in case of internal or API error.
 */
static int
xmlSchemaValidateContent(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node)
{
    xmlNodePtr child;
    xmlSchemaTypePtr type;

    child = ctxt->node;
    type = ctxt->type;
    ctxt->cur = node;

    xmlSchemaValidateAttributes(ctxt, node, type->attributes);
    ctxt->cur = node;

    switch (type->type) {
        case XML_SCHEMA_TYPE_ANY:
            /* Any type will do it, fine */
            TODO                /* handle recursivity */
                break;
        case XML_SCHEMA_TYPE_COMPLEX:
            xmlSchemaValidateComplexType(ctxt, node);
            break;
        case XML_SCHEMA_TYPE_ELEMENT:{
                xmlSchemaElementPtr decl = (xmlSchemaElementPtr) type;

                /*
                 * Handle element reference here
                 */
                if (decl->ref != NULL) {
                    if (decl->refDecl == NULL) {
                        xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL, "Internal error: element reference %s not resolved\n", decl->ref, NULL);
                        return (-1);
                    }
                    ctxt->type = (xmlSchemaTypePtr) decl->refDecl;
                    decl = decl->refDecl;
                }
                xmlSchemaValidateElementType(ctxt, node);
                ctxt->type = type;
                break;
            }
        case XML_SCHEMA_TYPE_BASIC:
            xmlSchemaValidateBasicType(ctxt, node);
            break;
        case XML_SCHEMA_TYPE_FACET:
            TODO break;
        case XML_SCHEMA_TYPE_SIMPLE:
            xmlSchemaValidateSimpleType(ctxt, node);
            break;
        case XML_SCHEMA_TYPE_SEQUENCE:
            TODO break;
        case XML_SCHEMA_TYPE_CHOICE:
            TODO break;
        case XML_SCHEMA_TYPE_ALL:
            TODO break;
        case XML_SCHEMA_TYPE_SIMPLE_CONTENT:
            TODO break;
        case XML_SCHEMA_TYPE_COMPLEX_CONTENT:
            TODO break;
        case XML_SCHEMA_TYPE_UR:
            TODO break;
        case XML_SCHEMA_TYPE_RESTRICTION:
            /*xmlSchemaValidateRestrictionType(ctxt, node); */
            TODO break;
        case XML_SCHEMA_TYPE_EXTENSION:
            TODO break;
        case XML_SCHEMA_TYPE_ATTRIBUTE:
            TODO break;
        case XML_SCHEMA_TYPE_GROUP:
            TODO break;
        case XML_SCHEMA_TYPE_NOTATION:
            TODO break;
        case XML_SCHEMA_TYPE_LIST:
            TODO break;
        case XML_SCHEMA_TYPE_UNION:
            TODO break;
        case XML_SCHEMA_FACET_MININCLUSIVE:
            TODO break;
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
            TODO break;
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
            TODO break;
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
            TODO break;
        case XML_SCHEMA_FACET_TOTALDIGITS:
            TODO break;
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
            TODO break;
        case XML_SCHEMA_FACET_PATTERN:
            TODO break;
        case XML_SCHEMA_FACET_ENUMERATION:
            TODO break;
        case XML_SCHEMA_FACET_WHITESPACE:
            TODO break;
        case XML_SCHEMA_FACET_LENGTH:
            TODO break;
        case XML_SCHEMA_FACET_MAXLENGTH:
            TODO break;
        case XML_SCHEMA_FACET_MINLENGTH:
            TODO break;
        case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
            TODO break;
    }
    xmlSchemaValidateAttributes(ctxt, node, type->attributes);

    if (ctxt->node == NULL)
        return (ctxt->err);
    ctxt->node = ctxt->node->next;
    ctxt->type = type->next;
    return (ctxt->err);
}

/**
 * xmlSchemaValidateType:
 * @ctxt:  a schema validation context
 * @elem:  an element
 * @type:  the list of type declarations
 *
 * Validate the content of an element against the types.
 *
 * Returns 0 if the element is schemas valid, a positive error code
 *     number otherwise and -1 in case of internal or API error.
 */
static int
xmlSchemaValidateType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem,
                      xmlSchemaElementPtr elemDecl, xmlSchemaTypePtr type)
{
    xmlChar *nil;

    if ((elem == NULL) || (type == NULL) || (elemDecl == NULL))
        return (0);

    /*
     * 3.3.4 : 2
     */
    if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
        xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_ISABSTRACT, "Element %s is abstract\n", elem->name, NULL);
        return (ctxt->err);
    }
    /*
     * 3.3.4: 3
     */
    nil = xmlGetNsProp(elem, BAD_CAST "nil", xmlSchemaInstanceNs);
    if (elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) {
        /* 3.3.4: 3.2 */
        if (xmlStrEqual(nil, BAD_CAST "true")) {
            if (elem->children != NULL) {
                xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_NOTEMPTY, "Element %s is not empty\n", elem->name, NULL);
                return (ctxt->err);
            }
            if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
                (elemDecl->value != NULL)) {
                xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_HAVEDEFAULT, "Empty element %s cannot get a fixed value\n", elem->name, NULL);
                return (ctxt->err);
            }
        }
    } else {
        /* 3.3.4: 3.1 */
        if (nil != NULL) {
            xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_NOTNILLABLE, "Element %s with xs:nil but not nillable\n", elem->name, NULL);
            xmlFree(nil);
            return (ctxt->err);
        }
    }

    /* TODO 3.3.4: 4 if the element carries xs:type */

    ctxt->type = elemDecl->subtypes;
    ctxt->node = elem->children;
    xmlSchemaValidateContent(ctxt, elem);
    xmlSchemaValidateAttributes(ctxt, elem, elemDecl->attributes);

    return (ctxt->err);
}


/**
 * xmlSchemaValidateAttributes:
 * @ctxt:  a schema validation context
 * @elem:  an element
 * @attributes:  the list of attribute declarations
 *
 * Validate the attributes of an element.
 *
 * Returns 0 if the element is schemas valid, a positive error code
 *     number otherwise and -1 in case of internal or API error.
 */
static int
xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem,
                            xmlSchemaAttributePtr attributes)
{
    int i, ret;
    xmlAttrPtr attr;
    xmlChar *value;
    xmlSchemaAttributeGroupPtr group = NULL;

    if (attributes == NULL)
        return (0);
    while (attributes != NULL) {
        /*
         * Handle attribute groups
         */
        if (attributes->type == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
            group = (xmlSchemaAttributeGroupPtr) attributes;
            xmlSchemaValidateAttributes(ctxt, elem, group->attributes);
            attributes = group->next;
            continue;
        }
        for (i = ctxt->attrBase; i < ctxt->attrNr; i++) {
            attr = ctxt->attr[i].attr;
            if (attr == NULL)
                continue;
            if (attributes->ref != NULL) {
                if (!xmlStrEqual(attr->name, attributes->ref))
                    continue;
                if (attr->ns != NULL) {
                    if ((attributes->refNs == NULL) ||
                        (!xmlStrEqual(attr->ns->href, attributes->refNs)))
                        continue;
                } else if (attributes->refNs != NULL) {
                    continue;
                }
            } else {
                if (!xmlStrEqual(attr->name, attributes->name))
                    continue;
                /*
                 * handle the namespaces checks here
                 */
                if (attr->ns == NULL) {
		    /*
		     * accept an unqualified attribute only if the declaration
		     * is unqualified or if the schemas allowed it.
		     */
		    if ((attributes->targetNamespace != NULL) &&
		        ((attributes->flags & XML_SCHEMAS_ATTR_NSDEFAULT) == 0))
		        continue;
		} else {
		    if (attributes->targetNamespace == NULL)
		        continue;
		    if (!xmlStrEqual(attributes->targetNamespace,
		                     attr->ns->href))
			continue;
		}
            }
            ctxt->cur = (xmlNodePtr) attributes;
            if (attributes->subtypes == NULL) {
                xmlSchemaVErr(ctxt, (xmlNodePtr) attr, XML_SCHEMAS_ERR_INTERNAL, "Internal error: attribute %s type not resolved\n", attr->name, NULL);
                continue;
            }
            value = xmlNodeListGetString(elem->doc, attr->children, 1);
            ret = xmlSchemaValidateSimpleValue(ctxt, attributes->subtypes,
                                               value);
            if (ret != 0) {
                xmlSchemaVErr(ctxt, (xmlNodePtr) attr, XML_SCHEMAS_ERR_ATTRINVALID, "attribute %s on %s does not match type\n", attr->name, elem->name);
            } else {
                ctxt->attr[i].state = XML_SCHEMAS_ATTR_CHECKED;
            }
            if (value != NULL) {
                xmlFree(value);
            }
        }
        attributes = attributes->next;
    }
    return (ctxt->err);
}

/**
 * xmlSchemaValidateElement:
 * @ctxt:  a schema validation context
 * @elem:  an element
 *
 * Validate an element in a tree
 *
 * Returns 0 if the element is schemas valid, a positive error code
 *     number otherwise and -1 in case of internal or API error.
 */
static int
xmlSchemaValidateElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
{
    xmlSchemaElementPtr elemDecl;
    int ret, attrBase;

    if (elem->ns != NULL) {
        elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
                                  elem->name, elem->ns->href, NULL);
    } else {
        elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
                                  elem->name, NULL, NULL);
    }
    /*
     * special case whe elementFormDefault is unqualified for top-level elem.
     */
    if ((elemDecl == NULL) && (elem->ns != NULL) &&
        (elem->parent != NULL) && (elem->parent->type != XML_ELEMENT_NODE) &&
        (xmlStrEqual(ctxt->schema->targetNamespace, elem->ns->href)) &&
	((ctxt->schema->flags & XML_SCHEMAS_QUALIF_ELEM) == 0)) {
        elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
                                  elem->name, NULL, NULL);
    }

    /*
     * 3.3.4 : 1
     */
    if (elemDecl == NULL) {
        xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_UNDECLAREDELEM, "Element %s not declared\n", elem->name, NULL);
        return (ctxt->err);
    }
    if (elemDecl->subtypes == NULL) {
        xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_NOTYPE, "Element %s has no type\n", elem->name, NULL);
        return (ctxt->err);
    }
    /*
     * Verify the attributes
     */
    attrBase = ctxt->attrBase;
    ctxt->attrBase = ctxt->attrNr;
    xmlSchemaRegisterAttributes(ctxt, elem->properties);
    xmlSchemaValidateAttributes(ctxt, elem, elemDecl->attributes);
    /*
     * Verify the element content recursively
     */
    if (elemDecl->contModel != NULL) {
        ctxt->regexp = xmlRegNewExecCtxt(elemDecl->contModel,
                                         (xmlRegExecCallbacks)
                                         xmlSchemaValidateCallback, ctxt);
#ifdef DEBUG_AUTOMATA
        xmlGenericError(xmlGenericErrorContext, "====> %s\n", elem->name);
#endif
    }
    xmlSchemaValidateType(ctxt, elem, elemDecl, elemDecl->subtypes);
    if (elemDecl->contModel != NULL) {
        ret = xmlRegExecPushString(ctxt->regexp, NULL, NULL);
#ifdef DEBUG_AUTOMATA
        xmlGenericError(xmlGenericErrorContext,
                        "====> %s : %d\n", elem->name, ret);
#endif
        if (ret == 0) {
            xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_ELEMCONT, "Element %s content check failed\n", elem->name, NULL);
        } else if (ret < 0) {
            xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_ELEMCONT, "Element %s content check failed\n", elem->name, NULL);
#ifdef DEBUG_CONTENT
        } else {
            xmlGenericError(xmlGenericErrorContext,
                            "Element %s content check succeeded\n",
                            elem->name);

#endif
        }
        xmlRegFreeExecCtxt(ctxt->regexp);
    }
    /*
     * Verify that all attributes were Schemas-validated
     */
    xmlSchemaCheckAttributes(ctxt, elem);
    ctxt->attrNr = ctxt->attrBase;
    ctxt->attrBase = attrBase;

    return (ctxt->err);
}

/**
 * xmlSchemaValidateDocument:
 * @ctxt:  a schema validation context
 * @doc:  a parsed document tree
 *
 * Validate a document tree in memory.
 *
 * Returns 0 if the document is schemas valid, a positive error code
 *     number otherwise and -1 in case of internal or API error.
 */
static int
xmlSchemaValidateDocument(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
{
    xmlNodePtr root;
    xmlSchemaElementPtr elemDecl;

    root = xmlDocGetRootElement(doc);
    if (root == NULL) {
        xmlSchemaVErr(ctxt, (xmlNodePtr) doc, XML_SCHEMAS_ERR_NOROOT, "document has no root\n", NULL, NULL);
        return (ctxt->err);
    }
    if (root->ns != NULL)
        elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
                                  root->name, root->ns->href, NULL);
    else
        elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
                                  root->name, NULL, NULL);
    /*
     * special case whe elementFormDefault is unqualified for top-level elem.
     */
    if ((elemDecl == NULL) && (root->ns != NULL) &&
        (xmlStrEqual(ctxt->schema->targetNamespace, root->ns->href)) &&
	((ctxt->schema->flags & XML_SCHEMAS_QUALIF_ELEM) == 0)) {
        elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
                                  root->name, NULL, NULL);
    }

    if (elemDecl == NULL) {
        xmlSchemaVErr(ctxt, root, XML_SCHEMAS_ERR_UNDECLAREDELEM, "Element %s not declared\n", root->name, NULL);
    } else if ((elemDecl->flags & XML_SCHEMAS_ELEM_TOPLEVEL) == 0) {
        xmlSchemaVErr(ctxt, root, XML_SCHEMAS_ERR_NOTTOPLEVEL, "Root element %s not toplevel\n", root->name, NULL);
    }
    /*
     * Okay, start the recursive validation
     */
    xmlSchemaValidateElement(ctxt, root);

    return (ctxt->err);
}

/************************************************************************
 * 									*
 * 			SAX Validation code				*
 * 									*
 ************************************************************************/

/************************************************************************
 * 									*
 * 			Validation interfaces				*
 * 									*
 ************************************************************************/

/**
 * xmlSchemaNewValidCtxt:
 * @schema:  a precompiled XML Schemas
 *
 * Create an XML Schemas validation context based on the given schema
 *
 * Returns the validation context or NULL in case of error
 */
xmlSchemaValidCtxtPtr
xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
{
    xmlSchemaValidCtxtPtr ret;

    ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
    if (ret == NULL) {
        xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlSchemaValidCtxt));
    ret->schema = schema;
    ret->attrNr = 0;
    ret->attrMax = 10;
    ret->attr = (xmlSchemaAttrStatePtr) xmlMalloc(ret->attrMax *
                                                  sizeof
                                                  (xmlSchemaAttrState));
    if (ret->attr == NULL) {
        xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
        free(ret);
        return (NULL);
    }
    memset(ret->attr, 0, ret->attrMax * sizeof(xmlSchemaAttrState));
    return (ret);
}

/**
 * xmlSchemaFreeValidCtxt:
 * @ctxt:  the schema validation context
 *
 * Free the resources associated to the schema validation context
 */
void
xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
{
    if (ctxt == NULL)
        return;
    if (ctxt->attr != NULL)
        xmlFree(ctxt->attr);
    if (ctxt->value != NULL)
        xmlSchemaFreeValue(ctxt->value);
    xmlFree(ctxt);
}

/**
 * xmlSchemaSetValidErrors:
 * @ctxt:  a schema validation context
 * @err:  the error function
 * @warn: the warning function
 * @ctx: the functions context
 *
 * Set the error and warning callback informations
 */
void
xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
                        xmlSchemaValidityErrorFunc err,
                        xmlSchemaValidityWarningFunc warn, void *ctx)
{
    if (ctxt == NULL)
        return;
    ctxt->error = err;
    ctxt->warning = warn;
    ctxt->userData = ctx;
}

/**
 * xmlSchemaValidateDoc:
 * @ctxt:  a schema validation context
 * @doc:  a parsed document tree
 *
 * Validate a document tree in memory.
 *
 * Returns 0 if the document is schemas valid, a positive error code
 *     number otherwise and -1 in case of internal or API error.
 */
int
xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
{
    int ret;

    if ((ctxt == NULL) || (doc == NULL))
        return (-1);

    ctxt->doc = doc;
    ret = xmlSchemaValidateDocument(ctxt, doc);
    return (ret);
}

/**
 * xmlSchemaValidateStream:
 * @ctxt:  a schema validation context
 * @input:  the input to use for reading the data
 * @enc:  an optional encoding information
 * @sax:  a SAX handler for the resulting events
 * @user_data:  the context to provide to the SAX handler.
 *
 * Validate a document tree in memory.
 *
 * Returns 0 if the document is schemas valid, a positive error code
 *     number otherwise and -1 in case of internal or API error.
 */
int
xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
                        xmlParserInputBufferPtr input, xmlCharEncoding enc,
                        xmlSAXHandlerPtr sax, void *user_data)
{
    if ((ctxt == NULL) || (input == NULL))
        return (-1);
    ctxt->input = input;
    ctxt->enc = enc;
    ctxt->sax = sax;
    ctxt->user_data = user_data;
    TODO return (0);
}

#endif /* LIBXML_SCHEMAS_ENABLED */
