/*
 * relaxng.c : implementation of the Relax-NG handling and validity checking
 *
 * See Copyright for the status of this software.
 *
 * Daniel Veillard <veillard@redhat.com>
 */

/**
 * TODO:
 * - add support for DTD compatibility spec
 *   http://www.oasis-open.org/committees/relax-ng/compatibility-20011203.html
 * - report better mem allocations pbms at runtime and abort immediately.
 */

#define IN_LIBXML
#include "libxml.h"

#ifdef LIBXML_SCHEMAS_ENABLED

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

#include <libxml/relaxng.h>

#include <libxml/xmlschemastypes.h>
#include <libxml/xmlautomata.h>
#include <libxml/xmlregexp.h>
#include <libxml/xmlschemastypes.h>

#include "private/error.h"
#include "private/regexp.h"
#include "private/string.h"

/*
 * The Relax-NG namespace
 */
static const xmlChar *xmlRelaxNGNs = (const xmlChar *)
    "http://relaxng.org/ns/structure/1.0";

#define IS_RELAXNG(node, typ)						\
   ((node != NULL) && (node->ns != NULL) &&				\
    (node->type == XML_ELEMENT_NODE) &&					\
    (xmlStrEqual(node->name, (const xmlChar *) typ)) &&		\
    (xmlStrEqual(node->ns->href, xmlRelaxNGNs)))


#define MAX_ERROR 5

typedef struct _xmlRelaxNGSchema xmlRelaxNGSchema;
typedef xmlRelaxNGSchema *xmlRelaxNGSchemaPtr;

typedef struct _xmlRelaxNGDefine xmlRelaxNGDefine;
typedef xmlRelaxNGDefine *xmlRelaxNGDefinePtr;

typedef struct _xmlRelaxNGDocument xmlRelaxNGDocument;
typedef xmlRelaxNGDocument *xmlRelaxNGDocumentPtr;

typedef struct _xmlRelaxNGInclude xmlRelaxNGInclude;
typedef xmlRelaxNGInclude *xmlRelaxNGIncludePtr;

typedef enum {
    XML_RELAXNG_COMBINE_UNDEFINED = 0,  /* undefined */
    XML_RELAXNG_COMBINE_CHOICE, /* choice */
    XML_RELAXNG_COMBINE_INTERLEAVE      /* interleave */
} xmlRelaxNGCombine;

typedef enum {
    XML_RELAXNG_CONTENT_ERROR = -1,
    XML_RELAXNG_CONTENT_EMPTY = 0,
    XML_RELAXNG_CONTENT_SIMPLE,
    XML_RELAXNG_CONTENT_COMPLEX
} xmlRelaxNGContentType;

typedef struct _xmlRelaxNGGrammar xmlRelaxNGGrammar;
typedef xmlRelaxNGGrammar *xmlRelaxNGGrammarPtr;

struct _xmlRelaxNGGrammar {
    xmlRelaxNGGrammarPtr parent;        /* the parent grammar if any */
    xmlRelaxNGGrammarPtr children;      /* the children grammar if any */
    xmlRelaxNGGrammarPtr next;  /* the next grammar if any */
    xmlRelaxNGDefinePtr start;  /* <start> content */
    xmlRelaxNGCombine combine;  /* the default combine value */
    xmlRelaxNGDefinePtr startList;      /* list of <start> definitions */
    xmlHashTablePtr defs;       /* define* */
    xmlHashTablePtr refs;       /* references */
};


typedef enum {
    XML_RELAXNG_NOOP = -1,      /* a no operation from simplification  */
    XML_RELAXNG_EMPTY = 0,      /* an empty pattern */
    XML_RELAXNG_NOT_ALLOWED,    /* not allowed top */
    XML_RELAXNG_EXCEPT,         /* except present in nameclass defs */
    XML_RELAXNG_TEXT,           /* textual content */
    XML_RELAXNG_ELEMENT,        /* an element */
    XML_RELAXNG_DATATYPE,       /* external data type definition */
    XML_RELAXNG_PARAM,          /* external data type parameter */
    XML_RELAXNG_VALUE,          /* value from an external data type definition */
    XML_RELAXNG_LIST,           /* a list of patterns */
    XML_RELAXNG_ATTRIBUTE,      /* an attribute following a pattern */
    XML_RELAXNG_DEF,            /* a definition */
    XML_RELAXNG_REF,            /* reference to a definition */
    XML_RELAXNG_EXTERNALREF,    /* reference to an external def */
    XML_RELAXNG_PARENTREF,      /* reference to a def in the parent grammar */
    XML_RELAXNG_OPTIONAL,       /* optional patterns */
    XML_RELAXNG_ZEROORMORE,     /* zero or more non empty patterns */
    XML_RELAXNG_ONEORMORE,      /* one or more non empty patterns */
    XML_RELAXNG_CHOICE,         /* a choice between non empty patterns */
    XML_RELAXNG_GROUP,          /* a pair/group of non empty patterns */
    XML_RELAXNG_INTERLEAVE,     /* interleaving choice of non-empty patterns */
    XML_RELAXNG_START           /* Used to keep track of starts on grammars */
} xmlRelaxNGType;

#define IS_NULLABLE		(1 << 0)
#define IS_NOT_NULLABLE		(1 << 1)
#define IS_INDETERMINIST	(1 << 2)
#define IS_MIXED		(1 << 3)
#define IS_TRIABLE		(1 << 4)
#define IS_PROCESSED		(1 << 5)
#define IS_COMPILABLE		(1 << 6)
#define IS_NOT_COMPILABLE	(1 << 7)
#define IS_EXTERNAL_REF	        (1 << 8)

struct _xmlRelaxNGDefine {
    xmlRelaxNGType type;        /* the type of definition */
    xmlNodePtr node;            /* the node in the source */
    xmlChar *name;              /* the element local name if present */
    xmlChar *ns;                /* the namespace local name if present */
    xmlChar *value;             /* value when available */
    void *data;                 /* data lib or specific pointer */
    xmlRelaxNGDefinePtr content;        /* the expected content */
    xmlRelaxNGDefinePtr parent; /* the parent definition, if any */
    xmlRelaxNGDefinePtr next;   /* list within grouping sequences */
    xmlRelaxNGDefinePtr attrs;  /* list of attributes for elements */
    xmlRelaxNGDefinePtr nameClass;      /* the nameClass definition if any */
    xmlRelaxNGDefinePtr nextHash;       /* next define in defs/refs hash tables */
    short depth;                /* used for the cycle detection */
    short dflags;               /* define related flags */
    xmlRegexpPtr contModel;     /* a compiled content model if available */
};

/**
 * _xmlRelaxNG:
 *
 * A RelaxNGs definition
 */
struct _xmlRelaxNG {
    void *_private;             /* unused by the library for users or bindings */
    xmlRelaxNGGrammarPtr topgrammar;
    xmlDocPtr doc;

    int idref;                  /* requires idref checking */

    xmlHashTablePtr defs;       /* define */
    xmlHashTablePtr refs;       /* references */
    xmlRelaxNGDocumentPtr documents;    /* all the documents loaded */
    xmlRelaxNGIncludePtr includes;      /* all the includes loaded */
    int defNr;                  /* number of defines used */
    xmlRelaxNGDefinePtr *defTab;        /* pointer to the allocated definitions */

};

#define XML_RELAXNG_IN_ATTRIBUTE	(1 << 0)
#define XML_RELAXNG_IN_ONEORMORE	(1 << 1)
#define XML_RELAXNG_IN_LIST		(1 << 2)
#define XML_RELAXNG_IN_DATAEXCEPT	(1 << 3)
#define XML_RELAXNG_IN_START		(1 << 4)
#define XML_RELAXNG_IN_OOMGROUP		(1 << 5)
#define XML_RELAXNG_IN_OOMINTERLEAVE	(1 << 6)
#define XML_RELAXNG_IN_EXTERNALREF	(1 << 7)
#define XML_RELAXNG_IN_ANYEXCEPT	(1 << 8)
#define XML_RELAXNG_IN_NSEXCEPT		(1 << 9)

struct _xmlRelaxNGParserCtxt {
    void *userData;             /* user specific data block */
    xmlRelaxNGValidityErrorFunc error;  /* the callback in case of errors */
    xmlRelaxNGValidityWarningFunc warning;      /* the callback in case of warning */
    xmlStructuredErrorFunc serror;
    xmlRelaxNGValidErr err;

    xmlRelaxNGPtr schema;       /* The schema in use */
    xmlRelaxNGGrammarPtr grammar;       /* the current grammar */
    xmlRelaxNGGrammarPtr parentgrammar; /* the parent grammar */
    int flags;                  /* parser flags */
    int nbErrors;               /* number of errors at parse time */
    int nbWarnings;             /* number of warnings at parse time */
    const xmlChar *define;      /* the current define scope */
    xmlRelaxNGDefinePtr def;    /* the current define */

    int nbInterleaves;
    xmlHashTablePtr interleaves;        /* keep track of all the interleaves */

    xmlRelaxNGDocumentPtr documents;    /* all the documents loaded */
    xmlRelaxNGIncludePtr includes;      /* all the includes loaded */
    xmlChar *URL;
    xmlDocPtr document;

    int defNr;                  /* number of defines used */
    int defMax;                 /* number of defines allocated */
    xmlRelaxNGDefinePtr *defTab;        /* pointer to the allocated definitions */

    const char *buffer;
    int size;

    /* the document stack */
    xmlRelaxNGDocumentPtr doc;  /* Current parsed external ref */
    int docNr;                  /* Depth of the parsing stack */
    int docMax;                 /* Max depth of the parsing stack */
    xmlRelaxNGDocumentPtr *docTab;      /* array of docs */

    /* the include stack */
    xmlRelaxNGIncludePtr inc;   /* Current parsed include */
    int incNr;                  /* Depth of the include parsing stack */
    int incMax;                 /* Max depth of the parsing stack */
    xmlRelaxNGIncludePtr *incTab;       /* array of incs */

    int idref;                  /* requires idref checking */

    /* used to compile content models */
    xmlAutomataPtr am;          /* the automata */
    xmlAutomataStatePtr state;  /* used to build the automata */

    int crng;			/* compact syntax and other flags */
    int freedoc;		/* need to free the document */
};

#define FLAGS_IGNORABLE		1
#define FLAGS_NEGATIVE		2
#define FLAGS_MIXED_CONTENT	4
#define FLAGS_NOERROR		8

/**
 * xmlRelaxNGInterleaveGroup:
 *
 * A RelaxNGs partition set associated to lists of definitions
 */
typedef struct _xmlRelaxNGInterleaveGroup xmlRelaxNGInterleaveGroup;
typedef xmlRelaxNGInterleaveGroup *xmlRelaxNGInterleaveGroupPtr;
struct _xmlRelaxNGInterleaveGroup {
    xmlRelaxNGDefinePtr rule;   /* the rule to satisfy */
    xmlRelaxNGDefinePtr *defs;  /* the array of element definitions */
    xmlRelaxNGDefinePtr *attrs; /* the array of attributes definitions */
};

#define IS_DETERMINIST		1
#define IS_NEEDCHECK		2

/**
 * xmlRelaxNGPartitions:
 *
 * A RelaxNGs partition associated to an interleave group
 */
typedef struct _xmlRelaxNGPartition xmlRelaxNGPartition;
typedef xmlRelaxNGPartition *xmlRelaxNGPartitionPtr;
struct _xmlRelaxNGPartition {
    int nbgroups;               /* number of groups in the partitions */
    xmlHashTablePtr triage;     /* hash table used to direct nodes to the
                                 * right group when possible */
    int flags;                  /* determinist ? */
    xmlRelaxNGInterleaveGroupPtr *groups;
};

/**
 * xmlRelaxNGValidState:
 *
 * A RelaxNGs validation state
 */
#define MAX_ATTR 20
typedef struct _xmlRelaxNGValidState xmlRelaxNGValidState;
typedef xmlRelaxNGValidState *xmlRelaxNGValidStatePtr;
struct _xmlRelaxNGValidState {
    xmlNodePtr node;            /* the current node */
    xmlNodePtr seq;             /* the sequence of children left to validate */
    int nbAttrs;                /* the number of attributes */
    int maxAttrs;               /* the size of attrs */
    int nbAttrLeft;             /* the number of attributes left to validate */
    xmlChar *value;             /* the value when operating on string */
    xmlChar *endvalue;          /* the end value when operating on string */
    xmlAttrPtr *attrs;          /* the array of attributes */
};

/**
 * xmlRelaxNGStates:
 *
 * A RelaxNGs container for validation state
 */
typedef struct _xmlRelaxNGStates xmlRelaxNGStates;
typedef xmlRelaxNGStates *xmlRelaxNGStatesPtr;
struct _xmlRelaxNGStates {
    int nbState;                /* the number of states */
    int maxState;               /* the size of the array */
    xmlRelaxNGValidStatePtr *tabState;
};

#define ERROR_IS_DUP	1

/**
 * xmlRelaxNGValidError:
 *
 * A RelaxNGs validation error
 */
typedef struct _xmlRelaxNGValidError xmlRelaxNGValidError;
typedef xmlRelaxNGValidError *xmlRelaxNGValidErrorPtr;
struct _xmlRelaxNGValidError {
    xmlRelaxNGValidErr err;     /* the error number */
    int flags;                  /* flags */
    xmlNodePtr node;            /* the current node */
    xmlNodePtr seq;             /* the current child */
    const xmlChar *arg1;        /* first arg */
    const xmlChar *arg2;        /* second arg */
};

/**
 * xmlRelaxNGValidCtxt:
 *
 * A RelaxNGs validation context
 */

struct _xmlRelaxNGValidCtxt {
    void *userData;             /* user specific data block */
    xmlRelaxNGValidityErrorFunc error;  /* the callback in case of errors */
    xmlRelaxNGValidityWarningFunc warning;      /* the callback in case of warning */
    xmlStructuredErrorFunc serror;
    int nbErrors;               /* number of errors in validation */

    xmlRelaxNGPtr schema;       /* The schema in use */
    xmlDocPtr doc;              /* the document being validated */
    int flags;                  /* validation flags */
    int depth;                  /* validation depth */
    int idref;                  /* requires idref checking */
    int errNo;                  /* the first error found */

    /*
     * Errors accumulated in branches may have to be stacked to be
     * provided back when it's sure they affect validation.
     */
    xmlRelaxNGValidErrorPtr err;        /* Last error */
    int errNr;                  /* Depth of the error stack */
    int errMax;                 /* Max depth of the error stack */
    xmlRelaxNGValidErrorPtr errTab;     /* stack of errors */

    xmlRelaxNGValidStatePtr state;      /* the current validation state */
    xmlRelaxNGStatesPtr states; /* the accumulated state list */

    xmlRelaxNGStatesPtr freeState;      /* the pool of free valid states */
    int freeStatesNr;
    int freeStatesMax;
    xmlRelaxNGStatesPtr *freeStates;    /* the pool of free state groups */

    /*
     * This is used for "progressive" validation
     */
    xmlRegExecCtxtPtr elem;     /* the current element regexp */
    int elemNr;                 /* the number of element validated */
    int elemMax;                /* the max depth of elements */
    xmlRegExecCtxtPtr *elemTab; /* the stack of regexp runtime */
    int pstate;                 /* progressive state */
    xmlNodePtr pnode;           /* the current node */
    xmlRelaxNGDefinePtr pdef;   /* the non-streamable definition */
    int perr;                   /* signal error in content model
                                 * outside the regexp */
};

/**
 * xmlRelaxNGInclude:
 *
 * Structure associated to a RelaxNGs document element
 */
struct _xmlRelaxNGInclude {
    xmlRelaxNGIncludePtr next;  /* keep a chain of includes */
    xmlChar *href;              /* the normalized href value */
    xmlDocPtr doc;              /* the associated XML document */
    xmlRelaxNGDefinePtr content;        /* the definitions */
    xmlRelaxNGPtr schema;       /* the schema */
};

/**
 * xmlRelaxNGDocument:
 *
 * Structure associated to a RelaxNGs document element
 */
struct _xmlRelaxNGDocument {
    xmlRelaxNGDocumentPtr next; /* keep a chain of documents */
    xmlChar *href;              /* the normalized href value */
    xmlDocPtr doc;              /* the associated XML document */
    xmlRelaxNGDefinePtr content;        /* the definitions */
    xmlRelaxNGPtr schema;       /* the schema */
    int externalRef;            /* 1 if an external ref */
};


/************************************************************************
 *									*
 *		Some factorized error routines				*
 *									*
 ************************************************************************/

/**
 * xmlRngPErrMemory:
 * @ctxt:  an Relax-NG parser context
 * @extra:  extra information
 *
 * Handle a redefinition of attribute error
 */
static void
xmlRngPErrMemory(xmlRelaxNGParserCtxtPtr ctxt)
{
    xmlStructuredErrorFunc schannel = NULL;
    xmlGenericErrorFunc channel = NULL;
    void *data = NULL;

    if (ctxt != NULL) {
        if (ctxt->serror != NULL)
	    schannel = ctxt->serror;
	else
	    channel = ctxt->error;
        data = ctxt->userData;
        ctxt->nbErrors++;
    }

    xmlRaiseMemoryError(schannel, channel, data, XML_FROM_RELAXNGP, NULL);
}

/**
 * xmlRngVErrMemory:
 * @ctxt:  a Relax-NG validation context
 * @extra:  extra information
 *
 * Handle a redefinition of attribute error
 */
static void
xmlRngVErrMemory(xmlRelaxNGValidCtxtPtr ctxt)
{
    xmlStructuredErrorFunc schannel = NULL;
    xmlGenericErrorFunc channel = NULL;
    void *data = NULL;

    if (ctxt != NULL) {
        if (ctxt->serror != NULL)
	    schannel = ctxt->serror;
	else
	    channel = ctxt->error;
        data = ctxt->userData;
        ctxt->nbErrors++;
    }

    xmlRaiseMemoryError(schannel, channel, data, XML_FROM_RELAXNGV, NULL);
}

/**
 * xmlRngPErr:
 * @ctxt:  a Relax-NG parser context
 * @node:  the node raising the error
 * @error:  the error code
 * @msg:  message
 * @str1:  extra info
 * @str2:  extra info
 *
 * Handle a Relax NG Parsing error
 */
static void LIBXML_ATTR_FORMAT(4,0)
xmlRngPErr(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node, int error,
           const char *msg, const xmlChar * str1, const xmlChar * str2)
{
    xmlStructuredErrorFunc schannel = NULL;
    xmlGenericErrorFunc channel = NULL;
    void *data = NULL;
    int res;

    if (ctxt != NULL) {
        if (ctxt->serror != NULL)
	    schannel = ctxt->serror;
	else
	    channel = ctxt->error;
        data = ctxt->userData;
        ctxt->nbErrors++;
    }

    if ((channel == NULL) && (schannel == NULL)) {
        channel = xmlGenericError;
        data = xmlGenericErrorContext;
    }

    res = __xmlRaiseError(schannel, channel, data, NULL, node,
                          XML_FROM_RELAXNGP, error, XML_ERR_ERROR, NULL, 0,
                          (const char *) str1, (const char *) str2, NULL, 0, 0,
                          msg, str1, str2);
    if (res < 0)
        xmlRngPErrMemory(ctxt);
}

/**
 * xmlRngVErr:
 * @ctxt:  a Relax-NG validation context
 * @node:  the node raising the error
 * @error:  the error code
 * @msg:  message
 * @str1:  extra info
 * @str2:  extra info
 *
 * Handle a Relax NG Validation error
 */
static void LIBXML_ATTR_FORMAT(4,0)
xmlRngVErr(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node, int error,
           const char *msg, const xmlChar * str1, const xmlChar * str2)
{
    xmlStructuredErrorFunc schannel = NULL;
    xmlGenericErrorFunc channel = NULL;
    void *data = NULL;
    int res;

    if (ctxt != NULL) {
        if (ctxt->serror != NULL)
	    schannel = ctxt->serror;
	else
	    channel = ctxt->error;
        data = ctxt->userData;
        ctxt->nbErrors++;
    }

    if ((channel == NULL) && (schannel == NULL)) {
        channel = xmlGenericError;
        data = xmlGenericErrorContext;
    }

    res = __xmlRaiseError(schannel, channel, data, NULL, node,
                          XML_FROM_RELAXNGV, error, XML_ERR_ERROR, NULL, 0,
                          (const char *) str1, (const char *) str2, NULL, 0, 0,
                          msg, str1, str2);
    if (res < 0)
        xmlRngVErrMemory(ctxt);
}

/************************************************************************
 *									*
 *		Preliminary type checking interfaces			*
 *									*
 ************************************************************************/

/**
 * xmlRelaxNGTypeHave:
 * @data:  data needed for the library
 * @type:  the type name
 * @value:  the value to check
 *
 * Function provided by a type library to check if a type is exported
 *
 * Returns 1 if yes, 0 if no and -1 in case of error.
 */
typedef int (*xmlRelaxNGTypeHave) (void *data, const xmlChar * type);

/**
 * xmlRelaxNGTypeCheck:
 * @data:  data needed for the library
 * @type:  the type name
 * @value:  the value to check
 * @result:  place to store the result if needed
 *
 * Function provided by a type library to check if a value match a type
 *
 * Returns 1 if yes, 0 if no and -1 in case of error.
 */
typedef int (*xmlRelaxNGTypeCheck) (void *data, const xmlChar * type,
                                    const xmlChar * value, void **result,
                                    xmlNodePtr node);

/**
 * xmlRelaxNGFacetCheck:
 * @data:  data needed for the library
 * @type:  the type name
 * @facet:  the facet name
 * @val:  the facet value
 * @strval:  the string value
 * @value:  the value to check
 *
 * Function provided by a type library to check a value facet
 *
 * Returns 1 if yes, 0 if no and -1 in case of error.
 */
typedef int (*xmlRelaxNGFacetCheck) (void *data, const xmlChar * type,
                                     const xmlChar * facet,
                                     const xmlChar * val,
                                     const xmlChar * strval, void *value);

/**
 * xmlRelaxNGTypeFree:
 * @data:  data needed for the library
 * @result:  the value to free
 *
 * Function provided by a type library to free a returned result
 */
typedef void (*xmlRelaxNGTypeFree) (void *data, void *result);

/**
 * xmlRelaxNGTypeCompare:
 * @data:  data needed for the library
 * @type:  the type name
 * @value1:  the first value
 * @value2:  the second value
 *
 * Function provided by a type library to compare two values accordingly
 * to a type.
 *
 * Returns 1 if yes, 0 if no and -1 in case of error.
 */
typedef int (*xmlRelaxNGTypeCompare) (void *data, const xmlChar * type,
                                      const xmlChar * value1,
                                      xmlNodePtr ctxt1,
                                      void *comp1,
                                      const xmlChar * value2,
                                      xmlNodePtr ctxt2);
typedef struct _xmlRelaxNGTypeLibrary xmlRelaxNGTypeLibrary;
typedef xmlRelaxNGTypeLibrary *xmlRelaxNGTypeLibraryPtr;
struct _xmlRelaxNGTypeLibrary {
    const xmlChar *namespace;   /* the datatypeLibrary value */
    void *data;                 /* data needed for the library */
    xmlRelaxNGTypeHave have;    /* the export function */
    xmlRelaxNGTypeCheck check;  /* the checking function */
    xmlRelaxNGTypeCompare comp; /* the compare function */
    xmlRelaxNGFacetCheck facet; /* the facet check function */
    xmlRelaxNGTypeFree freef;   /* the freeing function */
};

/************************************************************************
 *									*
 *			Allocation functions				*
 *									*
 ************************************************************************/
static void xmlRelaxNGFreeGrammar(xmlRelaxNGGrammarPtr grammar);
static void xmlRelaxNGFreeDefine(xmlRelaxNGDefinePtr define);
static void xmlRelaxNGNormExtSpace(xmlChar * value);
static void xmlRelaxNGFreeInnerSchema(xmlRelaxNGPtr schema);
static int xmlRelaxNGEqualValidState(xmlRelaxNGValidCtxtPtr ctxt
                                     ATTRIBUTE_UNUSED,
                                     xmlRelaxNGValidStatePtr state1,
                                     xmlRelaxNGValidStatePtr state2);
static void xmlRelaxNGFreeValidState(xmlRelaxNGValidCtxtPtr ctxt,
                                     xmlRelaxNGValidStatePtr state);

/**
 * xmlRelaxNGFreeDocument:
 * @docu:  a document structure
 *
 * Deallocate a RelaxNG document structure.
 */
static void
xmlRelaxNGFreeDocument(xmlRelaxNGDocumentPtr docu)
{
    if (docu == NULL)
        return;

    if (docu->href != NULL)
        xmlFree(docu->href);
    if (docu->doc != NULL)
        xmlFreeDoc(docu->doc);
    if (docu->schema != NULL)
        xmlRelaxNGFreeInnerSchema(docu->schema);
    xmlFree(docu);
}

/**
 * xmlRelaxNGFreeDocumentList:
 * @docu:  a list of  document structure
 *
 * Deallocate a RelaxNG document structures.
 */
static void
xmlRelaxNGFreeDocumentList(xmlRelaxNGDocumentPtr docu)
{
    xmlRelaxNGDocumentPtr next;

    while (docu != NULL) {
        next = docu->next;
        xmlRelaxNGFreeDocument(docu);
        docu = next;
    }
}

/**
 * xmlRelaxNGFreeInclude:
 * @incl:  a include structure
 *
 * Deallocate a RelaxNG include structure.
 */
static void
xmlRelaxNGFreeInclude(xmlRelaxNGIncludePtr incl)
{
    if (incl == NULL)
        return;

    if (incl->href != NULL)
        xmlFree(incl->href);
    if (incl->doc != NULL)
        xmlFreeDoc(incl->doc);
    if (incl->schema != NULL)
        xmlRelaxNGFree(incl->schema);
    xmlFree(incl);
}

/**
 * xmlRelaxNGFreeIncludeList:
 * @incl:  a include structure list
 *
 * Deallocate a RelaxNG include structure.
 */
static void
xmlRelaxNGFreeIncludeList(xmlRelaxNGIncludePtr incl)
{
    xmlRelaxNGIncludePtr next;

    while (incl != NULL) {
        next = incl->next;
        xmlRelaxNGFreeInclude(incl);
        incl = next;
    }
}

/**
 * xmlRelaxNGNewRelaxNG:
 * @ctxt:  a Relax-NG validation context (optional)
 *
 * Allocate a new RelaxNG structure.
 *
 * Returns the newly allocated structure or NULL in case or error
 */
static xmlRelaxNGPtr
xmlRelaxNGNewRelaxNG(xmlRelaxNGParserCtxtPtr ctxt)
{
    xmlRelaxNGPtr ret;

    ret = (xmlRelaxNGPtr) xmlMalloc(sizeof(xmlRelaxNG));
    if (ret == NULL) {
        xmlRngPErrMemory(ctxt);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlRelaxNG));

    return (ret);
}

/**
 * xmlRelaxNGFreeInnerSchema:
 * @schema:  a schema structure
 *
 * Deallocate a RelaxNG schema structure.
 */
static void
xmlRelaxNGFreeInnerSchema(xmlRelaxNGPtr schema)
{
    if (schema == NULL)
        return;

    if (schema->doc != NULL)
        xmlFreeDoc(schema->doc);
    if (schema->defTab != NULL) {
        int i;

        for (i = 0; i < schema->defNr; i++)
            xmlRelaxNGFreeDefine(schema->defTab[i]);
        xmlFree(schema->defTab);
    }

    xmlFree(schema);
}

/**
 * xmlRelaxNGFree:
 * @schema:  a schema structure
 *
 * Deallocate a RelaxNG structure.
 */
void
xmlRelaxNGFree(xmlRelaxNGPtr schema)
{
    if (schema == NULL)
        return;

    if (schema->topgrammar != NULL)
        xmlRelaxNGFreeGrammar(schema->topgrammar);
    if (schema->doc != NULL)
        xmlFreeDoc(schema->doc);
    if (schema->documents != NULL)
        xmlRelaxNGFreeDocumentList(schema->documents);
    if (schema->includes != NULL)
        xmlRelaxNGFreeIncludeList(schema->includes);
    if (schema->defTab != NULL) {
        int i;

        for (i = 0; i < schema->defNr; i++)
            xmlRelaxNGFreeDefine(schema->defTab[i]);
        xmlFree(schema->defTab);
    }

    xmlFree(schema);
}

/**
 * xmlRelaxNGNewGrammar:
 * @ctxt:  a Relax-NG validation context (optional)
 *
 * Allocate a new RelaxNG grammar.
 *
 * Returns the newly allocated structure or NULL in case or error
 */
static xmlRelaxNGGrammarPtr
xmlRelaxNGNewGrammar(xmlRelaxNGParserCtxtPtr ctxt)
{
    xmlRelaxNGGrammarPtr ret;

    ret = (xmlRelaxNGGrammarPtr) xmlMalloc(sizeof(xmlRelaxNGGrammar));
    if (ret == NULL) {
        xmlRngPErrMemory(ctxt);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlRelaxNGGrammar));

    return (ret);
}

/**
 * xmlRelaxNGFreeGrammar:
 * @grammar:  a grammar structure
 *
 * Deallocate a RelaxNG grammar structure.
 */
static void
xmlRelaxNGFreeGrammar(xmlRelaxNGGrammarPtr grammar)
{
    if (grammar == NULL)
        return;

    if (grammar->children != NULL) {
        xmlRelaxNGFreeGrammar(grammar->children);
    }
    if (grammar->next != NULL) {
        xmlRelaxNGFreeGrammar(grammar->next);
    }
    if (grammar->refs != NULL) {
        xmlHashFree(grammar->refs, NULL);
    }
    if (grammar->defs != NULL) {
        xmlHashFree(grammar->defs, NULL);
    }

    xmlFree(grammar);
}

/**
 * xmlRelaxNGNewDefine:
 * @ctxt:  a Relax-NG validation context
 * @node:  the node in the input document.
 *
 * Allocate a new RelaxNG define.
 *
 * Returns the newly allocated structure or NULL in case or error
 */
static xmlRelaxNGDefinePtr
xmlRelaxNGNewDefine(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
{
    xmlRelaxNGDefinePtr ret;

    if (ctxt->defMax == 0) {
        ctxt->defMax = 16;
        ctxt->defNr = 0;
        ctxt->defTab = (xmlRelaxNGDefinePtr *)
            xmlMalloc(ctxt->defMax * sizeof(xmlRelaxNGDefinePtr));
        if (ctxt->defTab == NULL) {
            xmlRngPErrMemory(ctxt);
            return (NULL);
        }
    } else if (ctxt->defMax <= ctxt->defNr) {
        xmlRelaxNGDefinePtr *tmp;

        ctxt->defMax *= 2;
        tmp = (xmlRelaxNGDefinePtr *) xmlRealloc(ctxt->defTab,
                                                 ctxt->defMax *
                                                 sizeof
                                                 (xmlRelaxNGDefinePtr));
        if (tmp == NULL) {
            xmlRngPErrMemory(ctxt);
            return (NULL);
        }
        ctxt->defTab = tmp;
    }
    ret = (xmlRelaxNGDefinePtr) xmlMalloc(sizeof(xmlRelaxNGDefine));
    if (ret == NULL) {
        xmlRngPErrMemory(ctxt);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlRelaxNGDefine));
    ctxt->defTab[ctxt->defNr++] = ret;
    ret->node = node;
    ret->depth = -1;
    return (ret);
}

/**
 * xmlRelaxNGFreePartition:
 * @partitions:  a partition set structure
 *
 * Deallocate RelaxNG partition set structures.
 */
static void
xmlRelaxNGFreePartition(xmlRelaxNGPartitionPtr partitions)
{
    xmlRelaxNGInterleaveGroupPtr group;
    int j;

    if (partitions != NULL) {
        if (partitions->groups != NULL) {
            for (j = 0; j < partitions->nbgroups; j++) {
                group = partitions->groups[j];
                if (group != NULL) {
                    if (group->defs != NULL)
                        xmlFree(group->defs);
                    if (group->attrs != NULL)
                        xmlFree(group->attrs);
                    xmlFree(group);
                }
            }
            xmlFree(partitions->groups);
        }
        if (partitions->triage != NULL) {
            xmlHashFree(partitions->triage, NULL);
        }
        xmlFree(partitions);
    }
}

/**
 * xmlRelaxNGFreeDefine:
 * @define:  a define structure
 *
 * Deallocate a RelaxNG define structure.
 */
static void
xmlRelaxNGFreeDefine(xmlRelaxNGDefinePtr define)
{
    if (define == NULL)
        return;

    if ((define->type == XML_RELAXNG_VALUE) && (define->attrs != NULL)) {
        xmlRelaxNGTypeLibraryPtr lib;

        lib = (xmlRelaxNGTypeLibraryPtr) define->data;
        if ((lib != NULL) && (lib->freef != NULL))
            lib->freef(lib->data, (void *) define->attrs);
    }
    if ((define->data != NULL) && (define->type == XML_RELAXNG_INTERLEAVE))
        xmlRelaxNGFreePartition((xmlRelaxNGPartitionPtr) define->data);
    if ((define->data != NULL) && (define->type == XML_RELAXNG_CHOICE))
        xmlHashFree((xmlHashTablePtr) define->data, NULL);
    if (define->name != NULL)
        xmlFree(define->name);
    if (define->ns != NULL)
        xmlFree(define->ns);
    if (define->value != NULL)
        xmlFree(define->value);
    if (define->contModel != NULL)
        xmlRegFreeRegexp(define->contModel);
    xmlFree(define);
}

/**
 * xmlRelaxNGNewStates:
 * @ctxt:  a Relax-NG validation context
 * @size:  the default size for the container
 *
 * Allocate a new RelaxNG validation state container
 *
 * Returns the newly allocated structure or NULL in case or error
 */
static xmlRelaxNGStatesPtr
xmlRelaxNGNewStates(xmlRelaxNGValidCtxtPtr ctxt, int size)
{
    xmlRelaxNGStatesPtr ret;

    if ((ctxt != NULL) &&
        (ctxt->freeStates != NULL) && (ctxt->freeStatesNr > 0)) {
        ctxt->freeStatesNr--;
        ret = ctxt->freeStates[ctxt->freeStatesNr];
        ret->nbState = 0;
        return (ret);
    }
    if (size < 16)
        size = 16;

    ret = (xmlRelaxNGStatesPtr) xmlMalloc(sizeof(xmlRelaxNGStates) +
                                          (size -
                                           1) *
                                          sizeof(xmlRelaxNGValidStatePtr));
    if (ret == NULL) {
        xmlRngVErrMemory(ctxt);
        return (NULL);
    }
    ret->nbState = 0;
    ret->maxState = size;
    ret->tabState = (xmlRelaxNGValidStatePtr *) xmlMalloc((size) *
                                                          sizeof
                                                          (xmlRelaxNGValidStatePtr));
    if (ret->tabState == NULL) {
        xmlRngVErrMemory(ctxt);
        xmlFree(ret);
        return (NULL);
    }
    return (ret);
}

/**
 * xmlRelaxNGAddStateUniq:
 * @ctxt:  a Relax-NG validation context
 * @states:  the states container
 * @state:  the validation state
 *
 * Add a RelaxNG validation state to the container without checking
 * for unicity.
 *
 * Return 1 in case of success and 0 if this is a duplicate and -1 on error
 */
static int
xmlRelaxNGAddStatesUniq(xmlRelaxNGValidCtxtPtr ctxt,
                        xmlRelaxNGStatesPtr states,
                        xmlRelaxNGValidStatePtr state)
{
    if (state == NULL) {
        return (-1);
    }
    if (states->nbState >= states->maxState) {
        xmlRelaxNGValidStatePtr *tmp;
        int size;

        size = states->maxState * 2;
        tmp = (xmlRelaxNGValidStatePtr *) xmlRealloc(states->tabState,
                                                     (size) *
                                                     sizeof
                                                     (xmlRelaxNGValidStatePtr));
        if (tmp == NULL) {
            xmlRngVErrMemory(ctxt);
            return (-1);
        }
        states->tabState = tmp;
        states->maxState = size;
    }
    states->tabState[states->nbState++] = state;
    return (1);
}

/**
 * xmlRelaxNGAddState:
 * @ctxt:  a Relax-NG validation context
 * @states:  the states container
 * @state:  the validation state
 *
 * Add a RelaxNG validation state to the container
 *
 * Return 1 in case of success and 0 if this is a duplicate and -1 on error
 */
static int
xmlRelaxNGAddStates(xmlRelaxNGValidCtxtPtr ctxt,
                    xmlRelaxNGStatesPtr states,
                    xmlRelaxNGValidStatePtr state)
{
    int i;

    if (state == NULL || states == NULL) {
        return (-1);
    }
    if (states->nbState >= states->maxState) {
        xmlRelaxNGValidStatePtr *tmp;
        int size;

        size = states->maxState * 2;
        tmp = (xmlRelaxNGValidStatePtr *) xmlRealloc(states->tabState,
                                                     (size) *
                                                     sizeof
                                                     (xmlRelaxNGValidStatePtr));
        if (tmp == NULL) {
            xmlRngVErrMemory(ctxt);
            return (-1);
        }
        states->tabState = tmp;
        states->maxState = size;
    }
    for (i = 0; i < states->nbState; i++) {
        if (xmlRelaxNGEqualValidState(ctxt, state, states->tabState[i])) {
            xmlRelaxNGFreeValidState(ctxt, state);
            return (0);
        }
    }
    states->tabState[states->nbState++] = state;
    return (1);
}

/**
 * xmlRelaxNGFreeStates:
 * @ctxt:  a Relax-NG validation context
 * @states:  the container
 *
 * Free a RelaxNG validation state container
 */
static void
xmlRelaxNGFreeStates(xmlRelaxNGValidCtxtPtr ctxt,
                     xmlRelaxNGStatesPtr states)
{
    if (states == NULL)
        return;
    if ((ctxt != NULL) && (ctxt->freeStates == NULL)) {
        ctxt->freeStatesMax = 40;
        ctxt->freeStatesNr = 0;
        ctxt->freeStates = (xmlRelaxNGStatesPtr *)
            xmlMalloc(ctxt->freeStatesMax * sizeof(xmlRelaxNGStatesPtr));
        if (ctxt->freeStates == NULL) {
            xmlRngVErrMemory(ctxt);
        }
    } else if ((ctxt != NULL)
               && (ctxt->freeStatesNr >= ctxt->freeStatesMax)) {
        xmlRelaxNGStatesPtr *tmp;

        tmp = (xmlRelaxNGStatesPtr *) xmlRealloc(ctxt->freeStates,
                                                 2 * ctxt->freeStatesMax *
                                                 sizeof
                                                 (xmlRelaxNGStatesPtr));
        if (tmp == NULL) {
            xmlRngVErrMemory(ctxt);
            xmlFree(states->tabState);
            xmlFree(states);
            return;
        }
        ctxt->freeStates = tmp;
        ctxt->freeStatesMax *= 2;
    }
    if ((ctxt == NULL) || (ctxt->freeStates == NULL)) {
        xmlFree(states->tabState);
        xmlFree(states);
    } else {
        ctxt->freeStates[ctxt->freeStatesNr++] = states;
    }
}

/**
 * xmlRelaxNGNewValidState:
 * @ctxt:  a Relax-NG validation context
 * @node:  the current node or NULL for the document
 *
 * Allocate a new RelaxNG validation state
 *
 * Returns the newly allocated structure or NULL in case or error
 */
static xmlRelaxNGValidStatePtr
xmlRelaxNGNewValidState(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node)
{
    xmlRelaxNGValidStatePtr ret;
    xmlAttrPtr attr;
    xmlAttrPtr attrs[MAX_ATTR];
    int nbAttrs = 0;
    xmlNodePtr root = NULL;

    if (node == NULL) {
        root = xmlDocGetRootElement(ctxt->doc);
        if (root == NULL)
            return (NULL);
    } else {
        attr = node->properties;
        while (attr != NULL) {
            if (nbAttrs < MAX_ATTR)
                attrs[nbAttrs++] = attr;
            else
                nbAttrs++;
            attr = attr->next;
        }
    }
    if ((ctxt->freeState != NULL) && (ctxt->freeState->nbState > 0)) {
        ctxt->freeState->nbState--;
        ret = ctxt->freeState->tabState[ctxt->freeState->nbState];
    } else {
        ret =
            (xmlRelaxNGValidStatePtr)
            xmlMalloc(sizeof(xmlRelaxNGValidState));
        if (ret == NULL) {
            xmlRngVErrMemory(ctxt);
            return (NULL);
        }
        memset(ret, 0, sizeof(xmlRelaxNGValidState));
    }
    ret->value = NULL;
    ret->endvalue = NULL;
    if (node == NULL) {
        ret->node = (xmlNodePtr) ctxt->doc;
        ret->seq = root;
    } else {
        ret->node = node;
        ret->seq = node->children;
    }
    ret->nbAttrs = 0;
    if (nbAttrs > 0) {
        if (ret->attrs == NULL) {
            if (nbAttrs < 4)
                ret->maxAttrs = 4;
            else
                ret->maxAttrs = nbAttrs;
            ret->attrs = (xmlAttrPtr *) xmlMalloc(ret->maxAttrs *
                                                  sizeof(xmlAttrPtr));
            if (ret->attrs == NULL) {
                xmlRngVErrMemory(ctxt);
                return (ret);
            }
        } else if (ret->maxAttrs < nbAttrs) {
            xmlAttrPtr *tmp;

            tmp = (xmlAttrPtr *) xmlRealloc(ret->attrs, nbAttrs *
                                            sizeof(xmlAttrPtr));
            if (tmp == NULL) {
                xmlRngVErrMemory(ctxt);
                return (ret);
            }
            ret->attrs = tmp;
            ret->maxAttrs = nbAttrs;
        }
        ret->nbAttrs = nbAttrs;
        if (nbAttrs < MAX_ATTR) {
            memcpy(ret->attrs, attrs, sizeof(xmlAttrPtr) * nbAttrs);
        } else {
            attr = node->properties;
            nbAttrs = 0;
            while (attr != NULL) {
                ret->attrs[nbAttrs++] = attr;
                attr = attr->next;
            }
        }
    }
    ret->nbAttrLeft = ret->nbAttrs;
    return (ret);
}

/**
 * xmlRelaxNGCopyValidState:
 * @ctxt:  a Relax-NG validation context
 * @state:  a validation state
 *
 * Copy the validation state
 *
 * Returns the newly allocated structure or NULL in case or error
 */
static xmlRelaxNGValidStatePtr
xmlRelaxNGCopyValidState(xmlRelaxNGValidCtxtPtr ctxt,
                         xmlRelaxNGValidStatePtr state)
{
    xmlRelaxNGValidStatePtr ret;
    unsigned int maxAttrs;
    xmlAttrPtr *attrs;

    if (state == NULL)
        return (NULL);
    if ((ctxt->freeState != NULL) && (ctxt->freeState->nbState > 0)) {
        ctxt->freeState->nbState--;
        ret = ctxt->freeState->tabState[ctxt->freeState->nbState];
    } else {
        ret =
            (xmlRelaxNGValidStatePtr)
            xmlMalloc(sizeof(xmlRelaxNGValidState));
        if (ret == NULL) {
            xmlRngVErrMemory(ctxt);
            return (NULL);
        }
        memset(ret, 0, sizeof(xmlRelaxNGValidState));
    }
    attrs = ret->attrs;
    maxAttrs = ret->maxAttrs;
    memcpy(ret, state, sizeof(xmlRelaxNGValidState));
    ret->attrs = attrs;
    ret->maxAttrs = maxAttrs;
    if (state->nbAttrs > 0) {
        if (ret->attrs == NULL) {
            ret->maxAttrs = state->maxAttrs;
            ret->attrs = (xmlAttrPtr *) xmlMalloc(ret->maxAttrs *
                                                  sizeof(xmlAttrPtr));
            if (ret->attrs == NULL) {
                xmlRngVErrMemory(ctxt);
                ret->nbAttrs = 0;
                return (ret);
            }
        } else if (ret->maxAttrs < state->nbAttrs) {
            xmlAttrPtr *tmp;

            tmp = (xmlAttrPtr *) xmlRealloc(ret->attrs, state->maxAttrs *
                                            sizeof(xmlAttrPtr));
            if (tmp == NULL) {
                xmlRngVErrMemory(ctxt);
                ret->nbAttrs = 0;
                return (ret);
            }
            ret->maxAttrs = state->maxAttrs;
            ret->attrs = tmp;
        }
        memcpy(ret->attrs, state->attrs,
               state->nbAttrs * sizeof(xmlAttrPtr));
    }
    return (ret);
}

/**
 * xmlRelaxNGEqualValidState:
 * @ctxt:  a Relax-NG validation context
 * @state1:  a validation state
 * @state2:  a validation state
 *
 * Compare the validation states for equality
 *
 * Returns 1 if equal, 0 otherwise
 */
static int
xmlRelaxNGEqualValidState(xmlRelaxNGValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
                          xmlRelaxNGValidStatePtr state1,
                          xmlRelaxNGValidStatePtr state2)
{
    int i;

    if ((state1 == NULL) || (state2 == NULL))
        return (0);
    if (state1 == state2)
        return (1);
    if (state1->node != state2->node)
        return (0);
    if (state1->seq != state2->seq)
        return (0);
    if (state1->nbAttrLeft != state2->nbAttrLeft)
        return (0);
    if (state1->nbAttrs != state2->nbAttrs)
        return (0);
    if (state1->endvalue != state2->endvalue)
        return (0);
    if ((state1->value != state2->value) &&
        (!xmlStrEqual(state1->value, state2->value)))
        return (0);
    for (i = 0; i < state1->nbAttrs; i++) {
        if (state1->attrs[i] != state2->attrs[i])
            return (0);
    }
    return (1);
}

/**
 * xmlRelaxNGFreeValidState:
 * @state:  a validation state structure
 *
 * Deallocate a RelaxNG validation state structure.
 */
static void
xmlRelaxNGFreeValidState(xmlRelaxNGValidCtxtPtr ctxt,
                         xmlRelaxNGValidStatePtr state)
{
    if (state == NULL)
        return;

    if ((ctxt != NULL) && (ctxt->freeState == NULL)) {
        ctxt->freeState = xmlRelaxNGNewStates(ctxt, 40);
    }
    if ((ctxt == NULL) || (ctxt->freeState == NULL)) {
        if (state->attrs != NULL)
            xmlFree(state->attrs);
        xmlFree(state);
    } else {
        xmlRelaxNGAddStatesUniq(ctxt, ctxt->freeState, state);
    }
}

/************************************************************************
 *									*
 *			Semi internal functions				*
 *									*
 ************************************************************************/

/**
 * xmlRelaxParserSetFlag:
 * @ctxt: a RelaxNG parser context
 * @flags: a set of flags values
 *
 * Semi private function used to pass information to a parser context
 * which are a combination of xmlRelaxNGParserFlag .
 *
 * Returns 0 if success and -1 in case of error
 */
int
xmlRelaxParserSetFlag(xmlRelaxNGParserCtxtPtr ctxt, int flags)
{
    if (ctxt == NULL) return(-1);
    if (flags & XML_RELAXNGP_FREE_DOC) {
        ctxt->crng |= XML_RELAXNGP_FREE_DOC;
	flags -= XML_RELAXNGP_FREE_DOC;
    }
    if (flags & XML_RELAXNGP_CRNG) {
        ctxt->crng |= XML_RELAXNGP_CRNG;
	flags -= XML_RELAXNGP_CRNG;
    }
    if (flags != 0) return(-1);
    return(0);
}

/************************************************************************
 *									*
 *			Document functions				*
 *									*
 ************************************************************************/
static xmlDocPtr xmlRelaxNGCleanupDoc(xmlRelaxNGParserCtxtPtr ctxt,
                                      xmlDocPtr doc);

static xmlDoc *
xmlRelaxReadFile(xmlRelaxNGParserCtxtPtr ctxt, const char *filename) {
    xmlParserCtxtPtr pctxt;
    xmlDocPtr doc;

    pctxt = xmlNewParserCtxt();
    if (pctxt == NULL) {
        xmlRngPErrMemory(ctxt);
        return(NULL);
    }
    if (ctxt->serror != NULL)
        xmlCtxtSetErrorHandler(pctxt, ctxt->serror, ctxt->userData);
    doc = xmlCtxtReadFile(pctxt, filename, NULL, 0);
    xmlFreeParserCtxt(pctxt);

    return(doc);
}

static xmlDoc *
xmlRelaxReadMemory(xmlRelaxNGParserCtxtPtr ctxt, const char *buf, int size) {
    xmlParserCtxtPtr pctxt;
    xmlDocPtr doc;

    pctxt = xmlNewParserCtxt();
    if (pctxt == NULL) {
        xmlRngPErrMemory(ctxt);
        return(NULL);
    }
    if (ctxt->serror != NULL)
        xmlCtxtSetErrorHandler(pctxt, ctxt->serror, ctxt->userData);
    doc = xmlCtxtReadMemory(pctxt, buf, size, NULL, NULL, 0);
    xmlFreeParserCtxt(pctxt);

    return(doc);
}

/**
 * xmlRelaxNGIncludePush:
 * @ctxt:  the parser context
 * @value:  the element doc
 *
 * Pushes a new include on top of the include stack
 *
 * Returns 0 in case of error, the index in the stack otherwise
 */
static int
xmlRelaxNGIncludePush(xmlRelaxNGParserCtxtPtr ctxt,
                      xmlRelaxNGIncludePtr value)
{
    if (ctxt->incTab == NULL) {
        ctxt->incMax = 4;
        ctxt->incNr = 0;
        ctxt->incTab =
            (xmlRelaxNGIncludePtr *) xmlMalloc(ctxt->incMax *
                                               sizeof(ctxt->incTab[0]));
        if (ctxt->incTab == NULL) {
            xmlRngPErrMemory(ctxt);
            return (0);
        }
    }
    if (ctxt->incNr >= ctxt->incMax) {
        ctxt->incMax *= 2;
        ctxt->incTab =
            (xmlRelaxNGIncludePtr *) xmlRealloc(ctxt->incTab,
                                                ctxt->incMax *
                                                sizeof(ctxt->incTab[0]));
        if (ctxt->incTab == NULL) {
            xmlRngPErrMemory(ctxt);
            return (0);
        }
    }
    ctxt->incTab[ctxt->incNr] = value;
    ctxt->inc = value;
    return (ctxt->incNr++);
}

/**
 * xmlRelaxNGIncludePop:
 * @ctxt: the parser context
 *
 * Pops the top include from the include stack
 *
 * Returns the include just removed
 */
static xmlRelaxNGIncludePtr
xmlRelaxNGIncludePop(xmlRelaxNGParserCtxtPtr ctxt)
{
    xmlRelaxNGIncludePtr ret;

    if (ctxt->incNr <= 0)
        return (NULL);
    ctxt->incNr--;
    if (ctxt->incNr > 0)
        ctxt->inc = ctxt->incTab[ctxt->incNr - 1];
    else
        ctxt->inc = NULL;
    ret = ctxt->incTab[ctxt->incNr];
    ctxt->incTab[ctxt->incNr] = NULL;
    return (ret);
}

/**
 * xmlRelaxNGRemoveRedefine:
 * @ctxt: the parser context
 * @URL:  the normalized URL
 * @target:  the included target
 * @name:  the define name to eliminate
 *
 * Applies the elimination algorithm of 4.7
 *
 * Returns 0 in case of error, 1 in case of success.
 */
static int
xmlRelaxNGRemoveRedefine(xmlRelaxNGParserCtxtPtr ctxt,
                         const xmlChar * URL ATTRIBUTE_UNUSED,
                         xmlNodePtr target, const xmlChar * name)
{
    int found = 0;
    xmlNodePtr tmp, tmp2;
    xmlChar *name2;

    tmp = target;
    while (tmp != NULL) {
        tmp2 = tmp->next;
        if ((name == NULL) && (IS_RELAXNG(tmp, "start"))) {
            found = 1;
            xmlUnlinkNode(tmp);
            xmlFreeNode(tmp);
        } else if ((name != NULL) && (IS_RELAXNG(tmp, "define"))) {
            name2 = xmlGetProp(tmp, BAD_CAST "name");
            xmlRelaxNGNormExtSpace(name2);
            if (name2 != NULL) {
                if (xmlStrEqual(name, name2)) {
                    found = 1;
                    xmlUnlinkNode(tmp);
                    xmlFreeNode(tmp);
                }
                xmlFree(name2);
            }
        } else if (IS_RELAXNG(tmp, "include")) {
            xmlChar *href = NULL;
            xmlRelaxNGDocumentPtr inc = tmp->psvi;

            if ((inc != NULL) && (inc->doc != NULL) &&
                (inc->doc->children != NULL)) {

                if (xmlStrEqual
                    (inc->doc->children->name, BAD_CAST "grammar")) {
                    if (xmlRelaxNGRemoveRedefine(ctxt, href,
                                                 xmlDocGetRootElement(inc->doc)->children,
                                                 name) == 1) {
                        found = 1;
                    }
                }
            }
            if (xmlRelaxNGRemoveRedefine(ctxt, URL, tmp->children, name) == 1) {
                found = 1;
            }
        }
        tmp = tmp2;
    }
    return (found);
}

/**
 * xmlRelaxNGLoadInclude:
 * @ctxt: the parser context
 * @URL:  the normalized URL
 * @node: the include node.
 * @ns:  the namespace passed from the context.
 *
 * First lookup if the document is already loaded into the parser context,
 * check against recursion. If not found the resource is loaded and
 * the content is preprocessed before being returned back to the caller.
 *
 * Returns the xmlRelaxNGIncludePtr or NULL in case of error
 */
static xmlRelaxNGIncludePtr
xmlRelaxNGLoadInclude(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar * URL,
                      xmlNodePtr node, const xmlChar * ns)
{
    xmlRelaxNGIncludePtr ret = NULL;
    xmlDocPtr doc;
    int i;
    xmlNodePtr root, cur;

    /*
     * check against recursion in the stack
     */
    for (i = 0; i < ctxt->incNr; i++) {
        if (xmlStrEqual(ctxt->incTab[i]->href, URL)) {
            xmlRngPErr(ctxt, NULL, XML_RNGP_INCLUDE_RECURSE,
                       "Detected an Include recursion for %s\n", URL,
                       NULL);
            return (NULL);
        }
    }

    /*
     * load the document
     */
    doc = xmlRelaxReadFile(ctxt, (const char *) URL);
    if (doc == NULL) {
        xmlRngPErr(ctxt, node, XML_RNGP_PARSE_ERROR,
                   "xmlRelaxNG: could not load %s\n", URL, NULL);
        return (NULL);
    }

    /*
     * Allocate the document structures and register it first.
     */
    ret = (xmlRelaxNGIncludePtr) xmlMalloc(sizeof(xmlRelaxNGInclude));
    if (ret == NULL) {
        xmlRngPErrMemory(ctxt);
        xmlFreeDoc(doc);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlRelaxNGInclude));
    ret->doc = doc;
    ret->href = xmlStrdup(URL);
    ret->next = ctxt->includes;
    ctxt->includes = ret;

    /*
     * transmit the ns if needed
     */
    if (ns != NULL) {
        root = xmlDocGetRootElement(doc);
        if (root != NULL) {
            if (xmlHasProp(root, BAD_CAST "ns") == NULL) {
                xmlSetProp(root, BAD_CAST "ns", ns);
            }
        }
    }

    /*
     * push it on the stack
     */
    xmlRelaxNGIncludePush(ctxt, ret);

    /*
     * Some preprocessing of the document content, this include recursing
     * in the include stack.
     */

    doc = xmlRelaxNGCleanupDoc(ctxt, doc);
    if (doc == NULL) {
        ctxt->inc = NULL;
        return (NULL);
    }

    /*
     * Pop up the include from the stack
     */
    xmlRelaxNGIncludePop(ctxt);

    /*
     * Check that the top element is a grammar
     */
    root = xmlDocGetRootElement(doc);
    if (root == NULL) {
        xmlRngPErr(ctxt, node, XML_RNGP_EMPTY,
                   "xmlRelaxNG: included document is empty %s\n", URL,
                   NULL);
        return (NULL);
    }
    if (!IS_RELAXNG(root, "grammar")) {
        xmlRngPErr(ctxt, node, XML_RNGP_GRAMMAR_MISSING,
                   "xmlRelaxNG: included document %s root is not a grammar\n",
                   URL, NULL);
        return (NULL);
    }

    /*
     * Elimination of redefined rules in the include.
     */
    cur = node->children;
    while (cur != NULL) {
        if (IS_RELAXNG(cur, "start")) {
            int found = 0;

            found =
                xmlRelaxNGRemoveRedefine(ctxt, URL, root->children, NULL);
            if (!found) {
                xmlRngPErr(ctxt, node, XML_RNGP_START_MISSING,
                           "xmlRelaxNG: include %s has a start but not the included grammar\n",
                           URL, NULL);
            }
        } else if (IS_RELAXNG(cur, "define")) {
            xmlChar *name;

            name = xmlGetProp(cur, BAD_CAST "name");
            if (name == NULL) {
                xmlRngPErr(ctxt, node, XML_RNGP_NAME_MISSING,
                           "xmlRelaxNG: include %s has define without name\n",
                           URL, NULL);
            } else {
                int found;

                xmlRelaxNGNormExtSpace(name);
                found = xmlRelaxNGRemoveRedefine(ctxt, URL,
                                                 root->children, name);
                if (!found) {
                    xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_MISSING,
                               "xmlRelaxNG: include %s has a define %s but not the included grammar\n",
                               URL, name);
                }
                xmlFree(name);
            }
        }
        if (IS_RELAXNG(cur, "div") && cur->children != NULL) {
            cur = cur->children;
        } else {
            if (cur->next != NULL) {
                cur = cur->next;
            } else {
                while (cur->parent != node && cur->parent->next == NULL) {
                    cur = cur->parent;
                }
                cur = cur->parent != node ? cur->parent->next : NULL;
            }
        }
    }


    return (ret);
}

/**
 * xmlRelaxNGValidErrorPush:
 * @ctxt:  the validation context
 * @err:  the error code
 * @arg1:  the first string argument
 * @arg2:  the second string argument
 * @dup:  arg need to be duplicated
 *
 * Pushes a new error on top of the error stack
 *
 * Returns 0 in case of error, the index in the stack otherwise
 */
static int
xmlRelaxNGValidErrorPush(xmlRelaxNGValidCtxtPtr ctxt,
                         xmlRelaxNGValidErr err, const xmlChar * arg1,
                         const xmlChar * arg2, int dup)
{
    xmlRelaxNGValidErrorPtr cur;

    if (ctxt->errTab == NULL) {
        ctxt->errMax = 8;
        ctxt->errNr = 0;
        ctxt->errTab =
            (xmlRelaxNGValidErrorPtr) xmlMalloc(ctxt->errMax *
                                                sizeof
                                                (xmlRelaxNGValidError));
        if (ctxt->errTab == NULL) {
            xmlRngVErrMemory(ctxt);
            return (0);
        }
        ctxt->err = NULL;
    }
    if (ctxt->errNr >= ctxt->errMax) {
        ctxt->errMax *= 2;
        ctxt->errTab =
            (xmlRelaxNGValidErrorPtr) xmlRealloc(ctxt->errTab,
                                                 ctxt->errMax *
                                                 sizeof
                                                 (xmlRelaxNGValidError));
        if (ctxt->errTab == NULL) {
            xmlRngVErrMemory(ctxt);
            return (0);
        }
        ctxt->err = &ctxt->errTab[ctxt->errNr - 1];
    }
    if ((ctxt->err != NULL) && (ctxt->state != NULL) &&
        (ctxt->err->node == ctxt->state->node) && (ctxt->err->err == err))
        return (ctxt->errNr);
    cur = &ctxt->errTab[ctxt->errNr];
    cur->err = err;
    if (dup) {
        cur->arg1 = xmlStrdup(arg1);
        cur->arg2 = xmlStrdup(arg2);
        cur->flags = ERROR_IS_DUP;
    } else {
        cur->arg1 = arg1;
        cur->arg2 = arg2;
        cur->flags = 0;
    }
    if (ctxt->state != NULL) {
        cur->node = ctxt->state->node;
        cur->seq = ctxt->state->seq;
    } else {
        cur->node = NULL;
        cur->seq = NULL;
    }
    ctxt->err = cur;
    return (ctxt->errNr++);
}

/**
 * xmlRelaxNGValidErrorPop:
 * @ctxt: the validation context
 *
 * Pops the top error from the error stack
 */
static void
xmlRelaxNGValidErrorPop(xmlRelaxNGValidCtxtPtr ctxt)
{
    xmlRelaxNGValidErrorPtr cur;

    if (ctxt->errNr <= 0) {
        ctxt->err = NULL;
        return;
    }
    ctxt->errNr--;
    if (ctxt->errNr > 0)
        ctxt->err = &ctxt->errTab[ctxt->errNr - 1];
    else
        ctxt->err = NULL;
    cur = &ctxt->errTab[ctxt->errNr];
    if (cur->flags & ERROR_IS_DUP) {
        if (cur->arg1 != NULL)
            xmlFree((xmlChar *) cur->arg1);
        cur->arg1 = NULL;
        if (cur->arg2 != NULL)
            xmlFree((xmlChar *) cur->arg2);
        cur->arg2 = NULL;
        cur->flags = 0;
    }
}

/**
 * xmlRelaxNGDocumentPush:
 * @ctxt:  the parser context
 * @value:  the element doc
 *
 * Pushes a new doc on top of the doc stack
 *
 * Returns 0 in case of error, the index in the stack otherwise
 */
static int
xmlRelaxNGDocumentPush(xmlRelaxNGParserCtxtPtr ctxt,
                       xmlRelaxNGDocumentPtr value)
{
    if (ctxt->docTab == NULL) {
        ctxt->docMax = 4;
        ctxt->docNr = 0;
        ctxt->docTab =
            (xmlRelaxNGDocumentPtr *) xmlMalloc(ctxt->docMax *
                                                sizeof(ctxt->docTab[0]));
        if (ctxt->docTab == NULL) {
            xmlRngPErrMemory(ctxt);
            return (0);
        }
    }
    if (ctxt->docNr >= ctxt->docMax) {
        ctxt->docMax *= 2;
        ctxt->docTab =
            (xmlRelaxNGDocumentPtr *) xmlRealloc(ctxt->docTab,
                                                 ctxt->docMax *
                                                 sizeof(ctxt->docTab[0]));
        if (ctxt->docTab == NULL) {
            xmlRngPErrMemory(ctxt);
            return (0);
        }
    }
    ctxt->docTab[ctxt->docNr] = value;
    ctxt->doc = value;
    return (ctxt->docNr++);
}

/**
 * xmlRelaxNGDocumentPop:
 * @ctxt: the parser context
 *
 * Pops the top doc from the doc stack
 *
 * Returns the doc just removed
 */
static xmlRelaxNGDocumentPtr
xmlRelaxNGDocumentPop(xmlRelaxNGParserCtxtPtr ctxt)
{
    xmlRelaxNGDocumentPtr ret;

    if (ctxt->docNr <= 0)
        return (NULL);
    ctxt->docNr--;
    if (ctxt->docNr > 0)
        ctxt->doc = ctxt->docTab[ctxt->docNr - 1];
    else
        ctxt->doc = NULL;
    ret = ctxt->docTab[ctxt->docNr];
    ctxt->docTab[ctxt->docNr] = NULL;
    return (ret);
}

/**
 * xmlRelaxNGLoadExternalRef:
 * @ctxt: the parser context
 * @URL:  the normalized URL
 * @ns:  the inherited ns if any
 *
 * First lookup if the document is already loaded into the parser context,
 * check against recursion. If not found the resource is loaded and
 * the content is preprocessed before being returned back to the caller.
 *
 * Returns the xmlRelaxNGDocumentPtr or NULL in case of error
 */
static xmlRelaxNGDocumentPtr
xmlRelaxNGLoadExternalRef(xmlRelaxNGParserCtxtPtr ctxt,
                          const xmlChar * URL, const xmlChar * ns)
{
    xmlRelaxNGDocumentPtr ret = NULL;
    xmlDocPtr doc;
    xmlNodePtr root;
    int i;

    /*
     * check against recursion in the stack
     */
    for (i = 0; i < ctxt->docNr; i++) {
        if (xmlStrEqual(ctxt->docTab[i]->href, URL)) {
            xmlRngPErr(ctxt, NULL, XML_RNGP_EXTERNALREF_RECURSE,
                       "Detected an externalRef recursion for %s\n", URL,
                       NULL);
            return (NULL);
        }
    }

    /*
     * load the document
     */
    doc = xmlRelaxReadFile(ctxt, (const char *) URL);
    if (doc == NULL) {
        xmlRngPErr(ctxt, NULL, XML_RNGP_PARSE_ERROR,
                   "xmlRelaxNG: could not load %s\n", URL, NULL);
        return (NULL);
    }

    /*
     * Allocate the document structures and register it first.
     */
    ret = (xmlRelaxNGDocumentPtr) xmlMalloc(sizeof(xmlRelaxNGDocument));
    if (ret == NULL) {
        xmlRngPErrMemory(ctxt);
        xmlFreeDoc(doc);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlRelaxNGDocument));
    ret->doc = doc;
    ret->href = xmlStrdup(URL);
    ret->next = ctxt->documents;
    ret->externalRef = 1;
    ctxt->documents = ret;

    /*
     * transmit the ns if needed
     */
    if (ns != NULL) {
        root = xmlDocGetRootElement(doc);
        if (root != NULL) {
            if (xmlHasProp(root, BAD_CAST "ns") == NULL) {
                xmlSetProp(root, BAD_CAST "ns", ns);
            }
        }
    }

    /*
     * push it on the stack and register it in the hash table
     */
    xmlRelaxNGDocumentPush(ctxt, ret);

    /*
     * Some preprocessing of the document content
     */
    doc = xmlRelaxNGCleanupDoc(ctxt, doc);
    if (doc == NULL) {
        ctxt->doc = NULL;
        return (NULL);
    }

    xmlRelaxNGDocumentPop(ctxt);

    return (ret);
}

/************************************************************************
 *									*
 *			Error functions					*
 *									*
 ************************************************************************/

#define VALID_ERR(a) xmlRelaxNGAddValidError(ctxt, a, NULL, NULL, 0);
#define VALID_ERR2(a, b) xmlRelaxNGAddValidError(ctxt, a, b, NULL, 0);
#define VALID_ERR3(a, b, c) xmlRelaxNGAddValidError(ctxt, a, b, c, 0);
#define VALID_ERR2P(a, b) xmlRelaxNGAddValidError(ctxt, a, b, NULL, 1);
#define VALID_ERR3P(a, b, c) xmlRelaxNGAddValidError(ctxt, a, b, c, 1);

static const char *
xmlRelaxNGDefName(xmlRelaxNGDefinePtr def)
{
    if (def == NULL)
        return ("none");
    switch (def->type) {
        case XML_RELAXNG_EMPTY:
            return ("empty");
        case XML_RELAXNG_NOT_ALLOWED:
            return ("notAllowed");
        case XML_RELAXNG_EXCEPT:
            return ("except");
        case XML_RELAXNG_TEXT:
            return ("text");
        case XML_RELAXNG_ELEMENT:
            return ("element");
        case XML_RELAXNG_DATATYPE:
            return ("datatype");
        case XML_RELAXNG_VALUE:
            return ("value");
        case XML_RELAXNG_LIST:
            return ("list");
        case XML_RELAXNG_ATTRIBUTE:
            return ("attribute");
        case XML_RELAXNG_DEF:
            return ("def");
        case XML_RELAXNG_REF:
            return ("ref");
        case XML_RELAXNG_EXTERNALREF:
            return ("externalRef");
        case XML_RELAXNG_PARENTREF:
            return ("parentRef");
        case XML_RELAXNG_OPTIONAL:
            return ("optional");
        case XML_RELAXNG_ZEROORMORE:
            return ("zeroOrMore");
        case XML_RELAXNG_ONEORMORE:
            return ("oneOrMore");
        case XML_RELAXNG_CHOICE:
            return ("choice");
        case XML_RELAXNG_GROUP:
            return ("group");
        case XML_RELAXNG_INTERLEAVE:
            return ("interleave");
        case XML_RELAXNG_START:
            return ("start");
        case XML_RELAXNG_NOOP:
            return ("noop");
        case XML_RELAXNG_PARAM:
            return ("param");
    }
    return ("unknown");
}

/**
 * xmlRelaxNGGetErrorString:
 * @err:  the error code
 * @arg1:  the first string argument
 * @arg2:  the second string argument
 *
 * computes a formatted error string for the given error code and args
 *
 * Returns the error string, it must be deallocated by the caller
 */
static xmlChar *
xmlRelaxNGGetErrorString(xmlRelaxNGValidErr err, const xmlChar * arg1,
                         const xmlChar * arg2)
{
    char msg[1000];
    xmlChar *result;

    if (arg1 == NULL)
        arg1 = BAD_CAST "";
    if (arg2 == NULL)
        arg2 = BAD_CAST "";

    msg[0] = 0;
    switch (err) {
        case XML_RELAXNG_OK:
            return (NULL);
        case XML_RELAXNG_ERR_MEMORY:
            return (xmlCharStrdup("out of memory\n"));
        case XML_RELAXNG_ERR_TYPE:
            snprintf(msg, 1000, "failed to validate type %s\n", arg1);
            break;
        case XML_RELAXNG_ERR_TYPEVAL:
            snprintf(msg, 1000, "Type %s doesn't allow value '%s'\n", arg1,
                     arg2);
            break;
        case XML_RELAXNG_ERR_DUPID:
            snprintf(msg, 1000, "ID %s redefined\n", arg1);
            break;
        case XML_RELAXNG_ERR_TYPECMP:
            snprintf(msg, 1000, "failed to compare type %s\n", arg1);
            break;
        case XML_RELAXNG_ERR_NOSTATE:
            return (xmlCharStrdup("Internal error: no state\n"));
        case XML_RELAXNG_ERR_NODEFINE:
            return (xmlCharStrdup("Internal error: no define\n"));
        case XML_RELAXNG_ERR_INTERNAL:
            snprintf(msg, 1000, "Internal error: %s\n", arg1);
            break;
        case XML_RELAXNG_ERR_LISTEXTRA:
            snprintf(msg, 1000, "Extra data in list: %s\n", arg1);
            break;
        case XML_RELAXNG_ERR_INTERNODATA:
            return (xmlCharStrdup
                    ("Internal: interleave block has no data\n"));
        case XML_RELAXNG_ERR_INTERSEQ:
            return (xmlCharStrdup("Invalid sequence in interleave\n"));
        case XML_RELAXNG_ERR_INTEREXTRA:
            snprintf(msg, 1000, "Extra element %s in interleave\n", arg1);
            break;
        case XML_RELAXNG_ERR_ELEMNAME:
            snprintf(msg, 1000, "Expecting element %s, got %s\n", arg1,
                     arg2);
            break;
        case XML_RELAXNG_ERR_ELEMNONS:
            snprintf(msg, 1000, "Expecting a namespace for element %s\n",
                     arg1);
            break;
        case XML_RELAXNG_ERR_ELEMWRONGNS:
            snprintf(msg, 1000,
                     "Element %s has wrong namespace: expecting %s\n", arg1,
                     arg2);
            break;
        case XML_RELAXNG_ERR_ELEMWRONG:
            snprintf(msg, 1000, "Did not expect element %s there\n", arg1);
            break;
        case XML_RELAXNG_ERR_TEXTWRONG:
            snprintf(msg, 1000,
                     "Did not expect text in element %s content\n", arg1);
            break;
        case XML_RELAXNG_ERR_ELEMEXTRANS:
            snprintf(msg, 1000, "Expecting no namespace for element %s\n",
                     arg1);
            break;
        case XML_RELAXNG_ERR_ELEMNOTEMPTY:
            snprintf(msg, 1000, "Expecting element %s to be empty\n", arg1);
            break;
        case XML_RELAXNG_ERR_NOELEM:
            snprintf(msg, 1000, "Expecting an element %s, got nothing\n",
                     arg1);
            break;
        case XML_RELAXNG_ERR_NOTELEM:
            return (xmlCharStrdup("Expecting an element got text\n"));
        case XML_RELAXNG_ERR_ATTRVALID:
            snprintf(msg, 1000, "Element %s failed to validate attributes\n",
                     arg1);
            break;
        case XML_RELAXNG_ERR_CONTENTVALID:
            snprintf(msg, 1000, "Element %s failed to validate content\n",
                     arg1);
            break;
        case XML_RELAXNG_ERR_EXTRACONTENT:
            snprintf(msg, 1000, "Element %s has extra content: %s\n",
                     arg1, arg2);
            break;
        case XML_RELAXNG_ERR_INVALIDATTR:
            snprintf(msg, 1000, "Invalid attribute %s for element %s\n",
                     arg1, arg2);
            break;
        case XML_RELAXNG_ERR_LACKDATA:
            snprintf(msg, 1000, "Datatype element %s contains no data\n",
                     arg1);
            break;
        case XML_RELAXNG_ERR_DATAELEM:
            snprintf(msg, 1000, "Datatype element %s has child elements\n",
                     arg1);
            break;
        case XML_RELAXNG_ERR_VALELEM:
            snprintf(msg, 1000, "Value element %s has child elements\n",
                     arg1);
            break;
        case XML_RELAXNG_ERR_LISTELEM:
            snprintf(msg, 1000, "List element %s has child elements\n",
                     arg1);
            break;
        case XML_RELAXNG_ERR_DATATYPE:
            snprintf(msg, 1000, "Error validating datatype %s\n", arg1);
            break;
        case XML_RELAXNG_ERR_VALUE:
            snprintf(msg, 1000, "Error validating value %s\n", arg1);
            break;
        case XML_RELAXNG_ERR_LIST:
            return (xmlCharStrdup("Error validating list\n"));
        case XML_RELAXNG_ERR_NOGRAMMAR:
            return (xmlCharStrdup("No top grammar defined\n"));
        case XML_RELAXNG_ERR_EXTRADATA:
            return (xmlCharStrdup("Extra data in the document\n"));
        default:
            return (xmlCharStrdup("Unknown error !\n"));
    }
    if (msg[0] == 0) {
        snprintf(msg, 1000, "Unknown error code %d\n", err);
    }
    msg[1000 - 1] = 0;
    result = xmlCharStrdup(msg);
    return (xmlEscapeFormatString(&result));
}

/**
 * xmlRelaxNGShowValidError:
 * @ctxt:  the validation context
 * @err:  the error number
 * @node:  the node
 * @child:  the node child generating the problem.
 * @arg1:  the first argument
 * @arg2:  the second argument
 *
 * Show a validation error.
 */
static void
xmlRelaxNGShowValidError(xmlRelaxNGValidCtxtPtr ctxt,
                         xmlRelaxNGValidErr err, xmlNodePtr node,
                         xmlNodePtr child, const xmlChar * arg1,
                         const xmlChar * arg2)
{
    xmlChar *msg;

    if (ctxt->flags & FLAGS_NOERROR)
        return;

    msg = xmlRelaxNGGetErrorString(err, arg1, arg2);
    if (msg == NULL)
        return;

    if (ctxt->errNo == XML_RELAXNG_OK)
        ctxt->errNo = err;
    xmlRngVErr(ctxt, (child == NULL ? node : child), err,
               (const char *) msg, arg1, arg2);
    xmlFree(msg);
}

/**
 * xmlRelaxNGPopErrors:
 * @ctxt:  the validation context
 * @level:  the error level in the stack
 *
 * pop and discard all errors until the given level is reached
 */
static void
xmlRelaxNGPopErrors(xmlRelaxNGValidCtxtPtr ctxt, int level)
{
    int i;
    xmlRelaxNGValidErrorPtr err;

    for (i = level; i < ctxt->errNr; i++) {
        err = &ctxt->errTab[i];
        if (err->flags & ERROR_IS_DUP) {
            if (err->arg1 != NULL)
                xmlFree((xmlChar *) err->arg1);
            err->arg1 = NULL;
            if (err->arg2 != NULL)
                xmlFree((xmlChar *) err->arg2);
            err->arg2 = NULL;
            err->flags = 0;
        }
    }
    ctxt->errNr = level;
    if (ctxt->errNr <= 0)
        ctxt->err = NULL;
}

/**
 * xmlRelaxNGDumpValidError:
 * @ctxt:  the validation context
 *
 * Show all validation error over a given index.
 */
static void
xmlRelaxNGDumpValidError(xmlRelaxNGValidCtxtPtr ctxt)
{
    int i, j, k;
    xmlRelaxNGValidErrorPtr err, dup;

    for (i = 0, k = 0; i < ctxt->errNr; i++) {
        err = &ctxt->errTab[i];
        if (k < MAX_ERROR) {
            for (j = 0; j < i; j++) {
                dup = &ctxt->errTab[j];
                if ((err->err == dup->err) && (err->node == dup->node) &&
                    (xmlStrEqual(err->arg1, dup->arg1)) &&
                    (xmlStrEqual(err->arg2, dup->arg2))) {
                    goto skip;
                }
            }
            xmlRelaxNGShowValidError(ctxt, err->err, err->node, err->seq,
                                     err->arg1, err->arg2);
            k++;
        }
      skip:
        if (err->flags & ERROR_IS_DUP) {
            if (err->arg1 != NULL)
                xmlFree((xmlChar *) err->arg1);
            err->arg1 = NULL;
            if (err->arg2 != NULL)
                xmlFree((xmlChar *) err->arg2);
            err->arg2 = NULL;
            err->flags = 0;
        }
    }
    ctxt->errNr = 0;
}

/**
 * xmlRelaxNGAddValidError:
 * @ctxt:  the validation context
 * @err:  the error number
 * @arg1:  the first argument
 * @arg2:  the second argument
 * @dup:  need to dup the args
 *
 * Register a validation error, either generating it if it's sure
 * or stacking it for later handling if unsure.
 */
static void
xmlRelaxNGAddValidError(xmlRelaxNGValidCtxtPtr ctxt,
                        xmlRelaxNGValidErr err, const xmlChar * arg1,
                        const xmlChar * arg2, int dup)
{
    if (ctxt == NULL)
        return;
    if (ctxt->flags & FLAGS_NOERROR)
        return;

    /*
     * generate the error directly
     */
    if (((ctxt->flags & FLAGS_IGNORABLE) == 0) ||
	 (ctxt->flags & FLAGS_NEGATIVE)) {
        xmlNodePtr node, seq;

        /*
         * Flush first any stacked error which might be the
         * real cause of the problem.
         */
        if (ctxt->errNr != 0)
            xmlRelaxNGDumpValidError(ctxt);
        if (ctxt->state != NULL) {
            node = ctxt->state->node;
            seq = ctxt->state->seq;
        } else {
            node = seq = NULL;
        }
        if ((node == NULL) && (seq == NULL)) {
            node = ctxt->pnode;
        }
        xmlRelaxNGShowValidError(ctxt, err, node, seq, arg1, arg2);
    }
    /*
     * Stack the error for later processing if needed
     */
    else {
        xmlRelaxNGValidErrorPush(ctxt, err, arg1, arg2, dup);
    }
}


/************************************************************************
 *									*
 *			Type library hooks				*
 *									*
 ************************************************************************/
static xmlChar *xmlRelaxNGNormalize(xmlRelaxNGValidCtxtPtr ctxt,
                                    const xmlChar * str);

/**
 * xmlRelaxNGSchemaTypeHave:
 * @data:  data needed for the library
 * @type:  the type name
 *
 * Check if the given type is provided by
 * the W3C XMLSchema Datatype library.
 *
 * Returns 1 if yes, 0 if no and -1 in case of error.
 */
static int
xmlRelaxNGSchemaTypeHave(void *data ATTRIBUTE_UNUSED, const xmlChar * type)
{
    xmlSchemaTypePtr typ;

    if (type == NULL)
        return (-1);
    typ = xmlSchemaGetPredefinedType(type,
                                     BAD_CAST
                                     "http://www.w3.org/2001/XMLSchema");
    if (typ == NULL)
        return (0);
    return (1);
}

/**
 * xmlRelaxNGSchemaTypeCheck:
 * @data:  data needed for the library
 * @type:  the type name
 * @value:  the value to check
 * @node:  the node
 *
 * Check if the given type and value are validated by
 * the W3C XMLSchema Datatype library.
 *
 * Returns 1 if yes, 0 if no and -1 in case of error.
 */
static int
xmlRelaxNGSchemaTypeCheck(void *data ATTRIBUTE_UNUSED,
                          const xmlChar * type,
                          const xmlChar * value,
                          void **result, xmlNodePtr node)
{
    xmlSchemaTypePtr typ;
    int ret;

    if ((type == NULL) || (value == NULL))
        return (-1);
    typ = xmlSchemaGetPredefinedType(type,
                                     BAD_CAST
                                     "http://www.w3.org/2001/XMLSchema");
    if (typ == NULL)
        return (-1);
    ret = xmlSchemaValPredefTypeNode(typ, value,
                                     (xmlSchemaValPtr *) result, node);
    if (ret == 2)               /* special ID error code */
        return (2);
    if (ret == 0)
        return (1);
    if (ret > 0)
        return (0);
    return (-1);
}

/**
 * xmlRelaxNGSchemaFacetCheck:
 * @data:  data needed for the library
 * @type:  the type name
 * @facet:  the facet name
 * @val:  the facet value
 * @strval:  the string value
 * @value:  the value to check
 *
 * Function provided by a type library to check a value facet
 *
 * Returns 1 if yes, 0 if no and -1 in case of error.
 */
static int
xmlRelaxNGSchemaFacetCheck(void *data ATTRIBUTE_UNUSED,
                           const xmlChar * type, const xmlChar * facetname,
                           const xmlChar * val, const xmlChar * strval,
                           void *value)
{
    xmlSchemaFacetPtr facet;
    xmlSchemaTypePtr typ;
    int ret;

    if ((type == NULL) || (strval == NULL))
        return (-1);
    typ = xmlSchemaGetPredefinedType(type,
                                     BAD_CAST
                                     "http://www.w3.org/2001/XMLSchema");
    if (typ == NULL)
        return (-1);

    facet = xmlSchemaNewFacet();
    if (facet == NULL)
        return (-1);

    if (xmlStrEqual(facetname, BAD_CAST "minInclusive")) {
        facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
    } else if (xmlStrEqual(facetname, BAD_CAST "minExclusive")) {
        facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
    } else if (xmlStrEqual(facetname, BAD_CAST "maxInclusive")) {
        facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
    } else if (xmlStrEqual(facetname, BAD_CAST "maxExclusive")) {
        facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
    } else if (xmlStrEqual(facetname, BAD_CAST "totalDigits")) {
        facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
    } else if (xmlStrEqual(facetname, BAD_CAST "fractionDigits")) {
        facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
    } else if (xmlStrEqual(facetname, BAD_CAST "pattern")) {
        facet->type = XML_SCHEMA_FACET_PATTERN;
    } else if (xmlStrEqual(facetname, BAD_CAST "enumeration")) {
        facet->type = XML_SCHEMA_FACET_ENUMERATION;
    } else if (xmlStrEqual(facetname, BAD_CAST "whiteSpace")) {
        facet->type = XML_SCHEMA_FACET_WHITESPACE;
    } else if (xmlStrEqual(facetname, BAD_CAST "length")) {
        facet->type = XML_SCHEMA_FACET_LENGTH;
    } else if (xmlStrEqual(facetname, BAD_CAST "maxLength")) {
        facet->type = XML_SCHEMA_FACET_MAXLENGTH;
    } else if (xmlStrEqual(facetname, BAD_CAST "minLength")) {
        facet->type = XML_SCHEMA_FACET_MINLENGTH;
    } else {
        xmlSchemaFreeFacet(facet);
        return (-1);
    }
    facet->value = val;
    ret = xmlSchemaCheckFacet(facet, typ, NULL, type);
    if (ret != 0) {
        xmlSchemaFreeFacet(facet);
        return (-1);
    }
    ret = xmlSchemaValidateFacet(typ, facet, strval, value);
    xmlSchemaFreeFacet(facet);
    if (ret != 0)
        return (-1);
    return (0);
}

/**
 * xmlRelaxNGSchemaFreeValue:
 * @data:  data needed for the library
 * @value:  the value to free
 *
 * Function provided by a type library to free a Schemas value
 *
 * Returns 1 if yes, 0 if no and -1 in case of error.
 */
static void
xmlRelaxNGSchemaFreeValue(void *data ATTRIBUTE_UNUSED, void *value)
{
    xmlSchemaFreeValue(value);
}

/**
 * xmlRelaxNGSchemaTypeCompare:
 * @data:  data needed for the library
 * @type:  the type name
 * @value1:  the first value
 * @value2:  the second value
 *
 * Compare two values for equality accordingly a type from the W3C XMLSchema
 * Datatype library.
 *
 * Returns 1 if equal, 0 if no and -1 in case of error.
 */
static int
xmlRelaxNGSchemaTypeCompare(void *data ATTRIBUTE_UNUSED,
                            const xmlChar * type,
                            const xmlChar * value1,
                            xmlNodePtr ctxt1,
                            void *comp1,
                            const xmlChar * value2, xmlNodePtr ctxt2)
{
    int ret;
    xmlSchemaTypePtr typ;
    xmlSchemaValPtr res1 = NULL, res2 = NULL;

    if ((type == NULL) || (value1 == NULL) || (value2 == NULL))
        return (-1);
    typ = xmlSchemaGetPredefinedType(type,
                                     BAD_CAST
                                     "http://www.w3.org/2001/XMLSchema");
    if (typ == NULL)
        return (-1);
    if (comp1 == NULL) {
        ret = xmlSchemaValPredefTypeNode(typ, value1, &res1, ctxt1);
        if (ret != 0)
            return (-1);
        if (res1 == NULL)
            return (-1);
    } else {
        res1 = (xmlSchemaValPtr) comp1;
    }
    ret = xmlSchemaValPredefTypeNode(typ, value2, &res2, ctxt2);
    if (ret != 0) {
	if (res1 != (xmlSchemaValPtr) comp1)
	    xmlSchemaFreeValue(res1);
        return (-1);
    }
    ret = xmlSchemaCompareValues(res1, res2);
    if (res1 != (xmlSchemaValPtr) comp1)
        xmlSchemaFreeValue(res1);
    xmlSchemaFreeValue(res2);
    if (ret == -2)
        return (-1);
    if (ret == 0)
        return (1);
    return (0);
}

/**
 * xmlRelaxNGDefaultTypeHave:
 * @data:  data needed for the library
 * @type:  the type name
 *
 * Check if the given type is provided by
 * the default datatype library.
 *
 * Returns 1 if yes, 0 if no and -1 in case of error.
 */
static int
xmlRelaxNGDefaultTypeHave(void *data ATTRIBUTE_UNUSED,
                          const xmlChar * type)
{
    if (type == NULL)
        return (-1);
    if (xmlStrEqual(type, BAD_CAST "string"))
        return (1);
    if (xmlStrEqual(type, BAD_CAST "token"))
        return (1);
    return (0);
}

/**
 * xmlRelaxNGDefaultTypeCheck:
 * @data:  data needed for the library
 * @type:  the type name
 * @value:  the value to check
 * @node:  the node
 *
 * Check if the given type and value are validated by
 * the default datatype library.
 *
 * Returns 1 if yes, 0 if no and -1 in case of error.
 */
static int
xmlRelaxNGDefaultTypeCheck(void *data ATTRIBUTE_UNUSED,
                           const xmlChar * type ATTRIBUTE_UNUSED,
                           const xmlChar * value ATTRIBUTE_UNUSED,
                           void **result ATTRIBUTE_UNUSED,
                           xmlNodePtr node ATTRIBUTE_UNUSED)
{
    if (value == NULL)
        return (-1);
    if (xmlStrEqual(type, BAD_CAST "string"))
        return (1);
    if (xmlStrEqual(type, BAD_CAST "token")) {
        return (1);
    }

    return (0);
}

/**
 * xmlRelaxNGDefaultTypeCompare:
 * @data:  data needed for the library
 * @type:  the type name
 * @value1:  the first value
 * @value2:  the second value
 *
 * Compare two values accordingly a type from the default
 * datatype library.
 *
 * Returns 1 if yes, 0 if no and -1 in case of error.
 */
static int
xmlRelaxNGDefaultTypeCompare(void *data ATTRIBUTE_UNUSED,
                             const xmlChar * type,
                             const xmlChar * value1,
                             xmlNodePtr ctxt1 ATTRIBUTE_UNUSED,
                             void *comp1 ATTRIBUTE_UNUSED,
                             const xmlChar * value2,
                             xmlNodePtr ctxt2 ATTRIBUTE_UNUSED)
{
    int ret = -1;

    if (xmlStrEqual(type, BAD_CAST "string")) {
        ret = xmlStrEqual(value1, value2);
    } else if (xmlStrEqual(type, BAD_CAST "token")) {
        if (!xmlStrEqual(value1, value2)) {
            xmlChar *nval, *nvalue;

            /*
             * TODO: trivial optimizations are possible by
             * computing at compile-time
             */
            nval = xmlRelaxNGNormalize(NULL, value1);
            nvalue = xmlRelaxNGNormalize(NULL, value2);

            if ((nval == NULL) || (nvalue == NULL))
                ret = -1;
            else if (xmlStrEqual(nval, nvalue))
                ret = 1;
            else
                ret = 0;
            if (nval != NULL)
                xmlFree(nval);
            if (nvalue != NULL)
                xmlFree(nvalue);
        } else
            ret = 1;
    }
    return (ret);
}

static int xmlRelaxNGTypeInitialized = 0;
static xmlHashTablePtr xmlRelaxNGRegisteredTypes = NULL;

/**
 * xmlRelaxNGFreeTypeLibrary:
 * @lib:  the type library structure
 * @namespace:  the URI bound to the library
 *
 * Free the structure associated to the type library
 */
static void
xmlRelaxNGFreeTypeLibrary(void *payload,
                          const xmlChar * namespace ATTRIBUTE_UNUSED)
{
    xmlRelaxNGTypeLibraryPtr lib = (xmlRelaxNGTypeLibraryPtr) payload;
    if (lib == NULL)
        return;
    if (lib->namespace != NULL)
        xmlFree((xmlChar *) lib->namespace);
    xmlFree(lib);
}

/**
 * xmlRelaxNGRegisterTypeLibrary:
 * @namespace:  the URI bound to the library
 * @data:  data associated to the library
 * @have:  the provide function
 * @check:  the checking function
 * @comp:  the comparison function
 *
 * Register a new type library
 *
 * Returns 0 in case of success and -1 in case of error.
 */
static int
xmlRelaxNGRegisterTypeLibrary(const xmlChar * namespace, void *data,
                              xmlRelaxNGTypeHave have,
                              xmlRelaxNGTypeCheck check,
                              xmlRelaxNGTypeCompare comp,
                              xmlRelaxNGFacetCheck facet,
                              xmlRelaxNGTypeFree freef)
{
    xmlRelaxNGTypeLibraryPtr lib;
    int ret;

    if ((xmlRelaxNGRegisteredTypes == NULL) || (namespace == NULL) ||
        (check == NULL) || (comp == NULL))
        return (-1);
    if (xmlHashLookup(xmlRelaxNGRegisteredTypes, namespace) != NULL)
        return (-1);
    lib =
        (xmlRelaxNGTypeLibraryPtr)
        xmlMalloc(sizeof(xmlRelaxNGTypeLibrary));
    if (lib == NULL) {
        xmlRngVErrMemory(NULL);
        return (-1);
    }
    memset(lib, 0, sizeof(xmlRelaxNGTypeLibrary));
    lib->namespace = xmlStrdup(namespace);
    lib->data = data;
    lib->have = have;
    lib->comp = comp;
    lib->check = check;
    lib->facet = facet;
    lib->freef = freef;
    ret = xmlHashAddEntry(xmlRelaxNGRegisteredTypes, namespace, lib);
    if (ret < 0) {
        xmlRelaxNGFreeTypeLibrary(lib, namespace);
        return (-1);
    }
    return (0);
}

/**
 * xmlRelaxNGInitTypes:
 *
 * Initialize the default type libraries.
 *
 * Returns 0 in case of success and -1 in case of error.
 */
int
xmlRelaxNGInitTypes(void)
{
    if (xmlRelaxNGTypeInitialized != 0)
        return (0);
    xmlRelaxNGRegisteredTypes = xmlHashCreate(10);
    if (xmlRelaxNGRegisteredTypes == NULL)
        return (-1);
    xmlRelaxNGRegisterTypeLibrary(BAD_CAST
                                  "http://www.w3.org/2001/XMLSchema-datatypes",
                                  NULL, xmlRelaxNGSchemaTypeHave,
                                  xmlRelaxNGSchemaTypeCheck,
                                  xmlRelaxNGSchemaTypeCompare,
                                  xmlRelaxNGSchemaFacetCheck,
                                  xmlRelaxNGSchemaFreeValue);
    xmlRelaxNGRegisterTypeLibrary(xmlRelaxNGNs, NULL,
                                  xmlRelaxNGDefaultTypeHave,
                                  xmlRelaxNGDefaultTypeCheck,
                                  xmlRelaxNGDefaultTypeCompare, NULL,
                                  NULL);
    xmlRelaxNGTypeInitialized = 1;
    return (0);
}

/**
 * xmlRelaxNGCleanupTypes:
 *
 * DEPRECATED: This function will be made private. Call xmlCleanupParser
 * to free global state but see the warnings there. xmlCleanupParser
 * should be only called once at program exit. In most cases, you don't
 * have call cleanup functions at all.
 *
 * Cleanup the default Schemas type library associated to RelaxNG
 */
void
xmlRelaxNGCleanupTypes(void)
{
    xmlSchemaCleanupTypes();
    if (xmlRelaxNGTypeInitialized == 0)
        return;
    xmlHashFree(xmlRelaxNGRegisteredTypes, xmlRelaxNGFreeTypeLibrary);
    xmlRelaxNGTypeInitialized = 0;
}

/************************************************************************
 *									*
 *		Compiling element content into regexp			*
 *									*
 * Sometime the element content can be compiled into a pure regexp,	*
 * This allows a faster execution and streamability at that level	*
 *									*
 ************************************************************************/

static int xmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt,
                                xmlRelaxNGDefinePtr def);

/**
 * xmlRelaxNGIsCompilable:
 * @define:  the definition to check
 *
 * Check if a definition is nullable.
 *
 * Returns 1 if yes, 0 if no and -1 in case of error
 */
static int
xmlRelaxNGIsCompilable(xmlRelaxNGDefinePtr def)
{
    int ret = -1;

    if (def == NULL) {
        return (-1);
    }
    if ((def->type != XML_RELAXNG_ELEMENT) &&
        (def->dflags & IS_COMPILABLE))
        return (1);
    if ((def->type != XML_RELAXNG_ELEMENT) &&
        (def->dflags & IS_NOT_COMPILABLE))
        return (0);
    switch (def->type) {
        case XML_RELAXNG_NOOP:
            ret = xmlRelaxNGIsCompilable(def->content);
            break;
        case XML_RELAXNG_TEXT:
        case XML_RELAXNG_EMPTY:
            ret = 1;
            break;
        case XML_RELAXNG_ELEMENT:
            /*
             * Check if the element content is compilable
             */
            if (((def->dflags & IS_NOT_COMPILABLE) == 0) &&
                ((def->dflags & IS_COMPILABLE) == 0)) {
                xmlRelaxNGDefinePtr list;

                list = def->content;
                while (list != NULL) {
                    ret = xmlRelaxNGIsCompilable(list);
                    if (ret != 1)
                        break;
                    list = list->next;
                }
		/*
		 * Because the routine is recursive, we must guard against
		 * discovering both COMPILABLE and NOT_COMPILABLE
		 */
                if (ret == 0) {
		    def->dflags &= ~IS_COMPILABLE;
                    def->dflags |= IS_NOT_COMPILABLE;
		}
                if ((ret == 1) && !(def->dflags &= IS_NOT_COMPILABLE))
                    def->dflags |= IS_COMPILABLE;
            }
            /*
             * All elements return a compilable status unless they
             * are generic like anyName
             */
            if ((def->nameClass != NULL) || (def->name == NULL))
                ret = 0;
            else
                ret = 1;
            return (ret);
        case XML_RELAXNG_REF:
        case XML_RELAXNG_EXTERNALREF:
        case XML_RELAXNG_PARENTREF:
            if (def->depth == -20) {
                return (1);
            } else {
                xmlRelaxNGDefinePtr list;

                def->depth = -20;
                list = def->content;
                while (list != NULL) {
                    ret = xmlRelaxNGIsCompilable(list);
                    if (ret != 1)
                        break;
                    list = list->next;
                }
            }
            break;
        case XML_RELAXNG_START:
        case XML_RELAXNG_OPTIONAL:
        case XML_RELAXNG_ZEROORMORE:
        case XML_RELAXNG_ONEORMORE:
        case XML_RELAXNG_CHOICE:
        case XML_RELAXNG_GROUP:
        case XML_RELAXNG_DEF:{
                xmlRelaxNGDefinePtr list;

                list = def->content;
                while (list != NULL) {
                    ret = xmlRelaxNGIsCompilable(list);
                    if (ret != 1)
                        break;
                    list = list->next;
                }
                break;
            }
        case XML_RELAXNG_EXCEPT:
        case XML_RELAXNG_ATTRIBUTE:
        case XML_RELAXNG_INTERLEAVE:
        case XML_RELAXNG_DATATYPE:
        case XML_RELAXNG_LIST:
        case XML_RELAXNG_PARAM:
        case XML_RELAXNG_VALUE:
        case XML_RELAXNG_NOT_ALLOWED:
            ret = 0;
            break;
    }
    if (ret == 0)
        def->dflags |= IS_NOT_COMPILABLE;
    if (ret == 1)
        def->dflags |= IS_COMPILABLE;
    return (ret);
}

/**
 * xmlRelaxNGCompile:
 * ctxt:  the RelaxNG parser context
 * @define:  the definition tree to compile
 *
 * Compile the set of definitions, it works recursively, till the
 * element boundaries, where it tries to compile the content if possible
 *
 * Returns 0 if success and -1 in case of error
 */
static int
xmlRelaxNGCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
{
    int ret = 0;
    xmlRelaxNGDefinePtr list;

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

    switch (def->type) {
        case XML_RELAXNG_START:
            if ((xmlRelaxNGIsCompilable(def) == 1) && (def->depth != -25)) {
                xmlAutomataPtr oldam = ctxt->am;
                xmlAutomataStatePtr oldstate = ctxt->state;

                def->depth = -25;

                list = def->content;
                ctxt->am = xmlNewAutomata();
                if (ctxt->am == NULL)
                    return (-1);

                /*
                 * assume identical strings but not same pointer are different
                 * atoms, needed for non-determinism detection
                 * That way if 2 elements with the same name are in a choice
                 * branch the automata is found non-deterministic and
                 * we fallback to the normal validation which does the right
                 * thing of exploring both choices.
                 */
                xmlAutomataSetFlags(ctxt->am, 1);

                ctxt->state = xmlAutomataGetInitState(ctxt->am);
                while (list != NULL) {
                    xmlRelaxNGCompile(ctxt, list);
                    list = list->next;
                }
                xmlAutomataSetFinalState(ctxt->am, ctxt->state);
                if (xmlAutomataIsDeterminist(ctxt->am))
                    def->contModel = xmlAutomataCompile(ctxt->am);

                xmlFreeAutomata(ctxt->am);
                ctxt->state = oldstate;
                ctxt->am = oldam;
            }
            break;
        case XML_RELAXNG_ELEMENT:
            if ((ctxt->am != NULL) && (def->name != NULL)) {
                ctxt->state = xmlAutomataNewTransition2(ctxt->am,
                                                        ctxt->state, NULL,
                                                        def->name, def->ns,
                                                        def);
            }
            if ((def->dflags & IS_COMPILABLE) && (def->depth != -25)) {
                xmlAutomataPtr oldam = ctxt->am;
                xmlAutomataStatePtr oldstate = ctxt->state;

                def->depth = -25;

                list = def->content;
                ctxt->am = xmlNewAutomata();
                if (ctxt->am == NULL)
                    return (-1);
                xmlAutomataSetFlags(ctxt->am, 1);
                ctxt->state = xmlAutomataGetInitState(ctxt->am);
                while (list != NULL) {
                    xmlRelaxNGCompile(ctxt, list);
                    list = list->next;
                }
                xmlAutomataSetFinalState(ctxt->am, ctxt->state);
                def->contModel = xmlAutomataCompile(ctxt->am);
                if (!xmlRegexpIsDeterminist(def->contModel)) {
                    /*
                     * we can only use the automata if it is determinist
                     */
                    xmlRegFreeRegexp(def->contModel);
                    def->contModel = NULL;
                }
                xmlFreeAutomata(ctxt->am);
                ctxt->state = oldstate;
                ctxt->am = oldam;
            } else {
                xmlAutomataPtr oldam = ctxt->am;

                /*
                 * we can't build the content model for this element content
                 * but it still might be possible to build it for some of its
                 * children, recurse.
                 */
                ret = xmlRelaxNGTryCompile(ctxt, def);
                ctxt->am = oldam;
            }
            break;
        case XML_RELAXNG_NOOP:
            ret = xmlRelaxNGCompile(ctxt, def->content);
            break;
        case XML_RELAXNG_OPTIONAL:{
                xmlAutomataStatePtr oldstate = ctxt->state;

                list = def->content;
                while (list != NULL) {
                    xmlRelaxNGCompile(ctxt, list);
                    list = list->next;
                }
                xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
                break;
            }
        case XML_RELAXNG_ZEROORMORE:{
                xmlAutomataStatePtr oldstate;

                ctxt->state =
                    xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
                oldstate = ctxt->state;
                list = def->content;
                while (list != NULL) {
                    xmlRelaxNGCompile(ctxt, list);
                    list = list->next;
                }
                xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldstate);
                ctxt->state =
                    xmlAutomataNewEpsilon(ctxt->am, oldstate, NULL);
                break;
            }
        case XML_RELAXNG_ONEORMORE:{
                xmlAutomataStatePtr oldstate;

                list = def->content;
                while (list != NULL) {
                    xmlRelaxNGCompile(ctxt, list);
                    list = list->next;
                }
                oldstate = ctxt->state;
                list = def->content;
                while (list != NULL) {
                    xmlRelaxNGCompile(ctxt, list);
                    list = list->next;
                }
                xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldstate);
                ctxt->state =
                    xmlAutomataNewEpsilon(ctxt->am, oldstate, NULL);
                break;
            }
        case XML_RELAXNG_CHOICE:{
                xmlAutomataStatePtr target = NULL;
                xmlAutomataStatePtr oldstate = ctxt->state;

                list = def->content;
                while (list != NULL) {
                    ctxt->state = oldstate;
                    ret = xmlRelaxNGCompile(ctxt, list);
                    if (ret != 0)
                        break;
                    if (target == NULL)
                        target = ctxt->state;
                    else {
                        xmlAutomataNewEpsilon(ctxt->am, ctxt->state,
                                              target);
                    }
                    list = list->next;
                }
                ctxt->state = target;

                break;
            }
        case XML_RELAXNG_REF:
        case XML_RELAXNG_EXTERNALREF:
        case XML_RELAXNG_PARENTREF:
        case XML_RELAXNG_GROUP:
        case XML_RELAXNG_DEF:
            list = def->content;
            while (list != NULL) {
                ret = xmlRelaxNGCompile(ctxt, list);
                if (ret != 0)
                    break;
                list = list->next;
            }
            break;
        case XML_RELAXNG_TEXT:{
                xmlAutomataStatePtr oldstate;

                ctxt->state =
                    xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
                oldstate = ctxt->state;
                xmlRelaxNGCompile(ctxt, def->content);
                xmlAutomataNewTransition(ctxt->am, ctxt->state,
                                         ctxt->state, BAD_CAST "#text",
                                         NULL);
                ctxt->state =
                    xmlAutomataNewEpsilon(ctxt->am, oldstate, NULL);
                break;
            }
        case XML_RELAXNG_EMPTY:
            ctxt->state =
                xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
            break;
        case XML_RELAXNG_EXCEPT:
        case XML_RELAXNG_ATTRIBUTE:
        case XML_RELAXNG_INTERLEAVE:
        case XML_RELAXNG_NOT_ALLOWED:
        case XML_RELAXNG_DATATYPE:
        case XML_RELAXNG_LIST:
        case XML_RELAXNG_PARAM:
        case XML_RELAXNG_VALUE:
            /* This should not happen and generate an internal error */
            fprintf(stderr, "RNG internal error trying to compile %s\n",
                    xmlRelaxNGDefName(def));
            break;
    }
    return (ret);
}

/**
 * xmlRelaxNGTryCompile:
 * ctxt:  the RelaxNG parser context
 * @define:  the definition tree to compile
 *
 * Try to compile the set of definitions, it works recursively,
 * possibly ignoring parts which cannot be compiled.
 *
 * Returns 0 if success and -1 in case of error
 */
static int
xmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
{
    int ret = 0;
    xmlRelaxNGDefinePtr list;

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

    if ((def->type == XML_RELAXNG_START) ||
        (def->type == XML_RELAXNG_ELEMENT)) {
        ret = xmlRelaxNGIsCompilable(def);
        if ((def->dflags & IS_COMPILABLE) && (def->depth != -25)) {
            ctxt->am = NULL;
            ret = xmlRelaxNGCompile(ctxt, def);
            return (ret);
        }
    }
    switch (def->type) {
        case XML_RELAXNG_NOOP:
            ret = xmlRelaxNGTryCompile(ctxt, def->content);
            break;
        case XML_RELAXNG_TEXT:
        case XML_RELAXNG_DATATYPE:
        case XML_RELAXNG_LIST:
        case XML_RELAXNG_PARAM:
        case XML_RELAXNG_VALUE:
        case XML_RELAXNG_EMPTY:
        case XML_RELAXNG_ELEMENT:
            ret = 0;
            break;
        case XML_RELAXNG_OPTIONAL:
        case XML_RELAXNG_ZEROORMORE:
        case XML_RELAXNG_ONEORMORE:
        case XML_RELAXNG_CHOICE:
        case XML_RELAXNG_GROUP:
        case XML_RELAXNG_DEF:
        case XML_RELAXNG_START:
        case XML_RELAXNG_REF:
        case XML_RELAXNG_EXTERNALREF:
        case XML_RELAXNG_PARENTREF:
            list = def->content;
            while (list != NULL) {
                ret = xmlRelaxNGTryCompile(ctxt, list);
                if (ret != 0)
                    break;
                list = list->next;
            }
            break;
        case XML_RELAXNG_EXCEPT:
        case XML_RELAXNG_ATTRIBUTE:
        case XML_RELAXNG_INTERLEAVE:
        case XML_RELAXNG_NOT_ALLOWED:
            ret = 0;
            break;
    }
    return (ret);
}

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

static xmlRelaxNGDefinePtr xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr
                                                    ctxt, xmlNodePtr node);
static xmlRelaxNGDefinePtr xmlRelaxNGParseElement(xmlRelaxNGParserCtxtPtr
                                                  ctxt, xmlNodePtr node);
static xmlRelaxNGDefinePtr xmlRelaxNGParsePatterns(xmlRelaxNGParserCtxtPtr
                                                   ctxt, xmlNodePtr nodes,
                                                   int group);
static xmlRelaxNGDefinePtr xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr
                                                  ctxt, xmlNodePtr node);
static xmlRelaxNGPtr xmlRelaxNGParseDocument(xmlRelaxNGParserCtxtPtr ctxt,
                                             xmlNodePtr node);
static int xmlRelaxNGParseGrammarContent(xmlRelaxNGParserCtxtPtr ctxt,
                                         xmlNodePtr nodes);
static xmlRelaxNGDefinePtr xmlRelaxNGParseNameClass(xmlRelaxNGParserCtxtPtr
                                                    ctxt, xmlNodePtr node,
                                                    xmlRelaxNGDefinePtr
                                                    def);
static xmlRelaxNGGrammarPtr xmlRelaxNGParseGrammar(xmlRelaxNGParserCtxtPtr
                                                   ctxt, xmlNodePtr nodes);
static int xmlRelaxNGElementMatch(xmlRelaxNGValidCtxtPtr ctxt,
                                  xmlRelaxNGDefinePtr define,
                                  xmlNodePtr elem);


#define IS_BLANK_NODE(n) (xmlRelaxNGIsBlank((n)->content))

/**
 * xmlRelaxNGIsNullable:
 * @define:  the definition to verify
 *
 * Check if a definition is nullable.
 *
 * Returns 1 if yes, 0 if no and -1 in case of error
 */
static int
xmlRelaxNGIsNullable(xmlRelaxNGDefinePtr define)
{
    int ret;

    if (define == NULL)
        return (-1);

    if (define->dflags & IS_NULLABLE)
        return (1);
    if (define->dflags & IS_NOT_NULLABLE)
        return (0);
    switch (define->type) {
        case XML_RELAXNG_EMPTY:
        case XML_RELAXNG_TEXT:
            ret = 1;
            break;
        case XML_RELAXNG_NOOP:
        case XML_RELAXNG_DEF:
        case XML_RELAXNG_REF:
        case XML_RELAXNG_EXTERNALREF:
        case XML_RELAXNG_PARENTREF:
        case XML_RELAXNG_ONEORMORE:
            ret = xmlRelaxNGIsNullable(define->content);
            break;
        case XML_RELAXNG_EXCEPT:
        case XML_RELAXNG_NOT_ALLOWED:
        case XML_RELAXNG_ELEMENT:
        case XML_RELAXNG_DATATYPE:
        case XML_RELAXNG_PARAM:
        case XML_RELAXNG_VALUE:
        case XML_RELAXNG_LIST:
        case XML_RELAXNG_ATTRIBUTE:
            ret = 0;
            break;
        case XML_RELAXNG_CHOICE:{
                xmlRelaxNGDefinePtr list = define->content;

                while (list != NULL) {
                    ret = xmlRelaxNGIsNullable(list);
                    if (ret != 0)
                        goto done;
                    list = list->next;
                }
                ret = 0;
                break;
            }
        case XML_RELAXNG_START:
        case XML_RELAXNG_INTERLEAVE:
        case XML_RELAXNG_GROUP:{
                xmlRelaxNGDefinePtr list = define->content;

                while (list != NULL) {
                    ret = xmlRelaxNGIsNullable(list);
                    if (ret != 1)
                        goto done;
                    list = list->next;
                }
                return (1);
            }
        default:
            return (-1);
    }
  done:
    if (ret == 0)
        define->dflags |= IS_NOT_NULLABLE;
    if (ret == 1)
        define->dflags |= IS_NULLABLE;
    return (ret);
}

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

/**
 * xmlRelaxNGGetDataTypeLibrary:
 * @ctxt:  a Relax-NG parser context
 * @node:  the current data or value element
 *
 * Applies algorithm from 4.3. datatypeLibrary attribute
 *
 * Returns the datatypeLibrary value or NULL if not found
 */
static xmlChar *
xmlRelaxNGGetDataTypeLibrary(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
                             xmlNodePtr node)
{
    xmlChar *ret, *escape;

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

    if ((IS_RELAXNG(node, "data")) || (IS_RELAXNG(node, "value"))) {
        ret = xmlGetProp(node, BAD_CAST "datatypeLibrary");
        if (ret != NULL) {
            if (ret[0] == 0) {
                xmlFree(ret);
                return (NULL);
            }
            escape = xmlURIEscapeStr(ret, BAD_CAST ":/#?");
            if (escape == NULL) {
                return (ret);
            }
            xmlFree(ret);
            return (escape);
        }
    }
    node = node->parent;
    while ((node != NULL) && (node->type == XML_ELEMENT_NODE)) {
        ret = xmlGetProp(node, BAD_CAST "datatypeLibrary");
        if (ret != NULL) {
            if (ret[0] == 0) {
                xmlFree(ret);
                return (NULL);
            }
            escape = xmlURIEscapeStr(ret, BAD_CAST ":/#?");
            if (escape == NULL) {
                return (ret);
            }
            xmlFree(ret);
            return (escape);
        }
        node = node->parent;
    }
    return (NULL);
}

/**
 * xmlRelaxNGParseValue:
 * @ctxt:  a Relax-NG parser context
 * @node:  the data node.
 *
 * parse the content of a RelaxNG value node.
 *
 * Returns the definition pointer or NULL in case of error
 */
static xmlRelaxNGDefinePtr
xmlRelaxNGParseValue(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
{
    xmlRelaxNGDefinePtr def = NULL;
    xmlRelaxNGTypeLibraryPtr lib = NULL;
    xmlChar *type;
    xmlChar *library;
    int success = 0;

    def = xmlRelaxNGNewDefine(ctxt, node);
    if (def == NULL)
        return (NULL);
    def->type = XML_RELAXNG_VALUE;

    type = xmlGetProp(node, BAD_CAST "type");
    if (type != NULL) {
        xmlRelaxNGNormExtSpace(type);
        if (xmlValidateNCName(type, 0)) {
            xmlRngPErr(ctxt, node, XML_RNGP_TYPE_VALUE,
                       "value type '%s' is not an NCName\n", type, NULL);
        }
        library = xmlRelaxNGGetDataTypeLibrary(ctxt, node);
        if (library == NULL)
            library =
                xmlStrdup(BAD_CAST "http://relaxng.org/ns/structure/1.0");

        def->name = type;
        def->ns = library;

        lib = (xmlRelaxNGTypeLibraryPtr)
            xmlHashLookup(xmlRelaxNGRegisteredTypes, library);
        if (lib == NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_TYPE_LIB,
                       "Use of unregistered type library '%s'\n", library,
                       NULL);
            def->data = NULL;
        } else {
            def->data = lib;
            if (lib->have == NULL) {
                xmlRngPErr(ctxt, node, XML_RNGP_ERROR_TYPE_LIB,
                           "Internal error with type library '%s': no 'have'\n",
                           library, NULL);
            } else {
                success = lib->have(lib->data, def->name);
                if (success != 1) {
                    xmlRngPErr(ctxt, node, XML_RNGP_TYPE_NOT_FOUND,
                               "Error type '%s' is not exported by type library '%s'\n",
                               def->name, library);
                }
            }
        }
    }
    if (node->children == NULL) {
        def->value = xmlStrdup(BAD_CAST "");
    } else if (((node->children->type != XML_TEXT_NODE) &&
                (node->children->type != XML_CDATA_SECTION_NODE)) ||
               (node->children->next != NULL)) {
        xmlRngPErr(ctxt, node, XML_RNGP_TEXT_EXPECTED,
                   "Expecting a single text value for <value>content\n",
                   NULL, NULL);
    } else if (def != NULL) {
        def->value = xmlNodeGetContent(node);
        if (def->value == NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_VALUE_NO_CONTENT,
                       "Element <value> has no content\n", NULL, NULL);
        } else if ((lib != NULL) && (lib->check != NULL) && (success == 1)) {
            void *val = NULL;

            success =
                lib->check(lib->data, def->name, def->value, &val, node);
            if (success != 1) {
                xmlRngPErr(ctxt, node, XML_RNGP_INVALID_VALUE,
                           "Value '%s' is not acceptable for type '%s'\n",
                           def->value, def->name);
            } else {
                if (val != NULL)
                    def->attrs = val;
            }
        }
    }
    return (def);
}

/**
 * xmlRelaxNGParseData:
 * @ctxt:  a Relax-NG parser context
 * @node:  the data node.
 *
 * parse the content of a RelaxNG data node.
 *
 * Returns the definition pointer or NULL in case of error
 */
static xmlRelaxNGDefinePtr
xmlRelaxNGParseData(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
{
    xmlRelaxNGDefinePtr def = NULL, except;
    xmlRelaxNGDefinePtr param, lastparam = NULL;
    xmlRelaxNGTypeLibraryPtr lib;
    xmlChar *type;
    xmlChar *library;
    xmlNodePtr content;
    int tmp;

    type = xmlGetProp(node, BAD_CAST "type");
    if (type == NULL) {
        xmlRngPErr(ctxt, node, XML_RNGP_TYPE_MISSING, "data has no type\n", NULL,
                   NULL);
        return (NULL);
    }
    xmlRelaxNGNormExtSpace(type);
    if (xmlValidateNCName(type, 0)) {
        xmlRngPErr(ctxt, node, XML_RNGP_TYPE_VALUE,
                   "data type '%s' is not an NCName\n", type, NULL);
    }
    library = xmlRelaxNGGetDataTypeLibrary(ctxt, node);
    if (library == NULL)
        library =
            xmlStrdup(BAD_CAST "http://relaxng.org/ns/structure/1.0");

    def = xmlRelaxNGNewDefine(ctxt, node);
    if (def == NULL) {
        xmlFree(library);
        xmlFree(type);
        return (NULL);
    }
    def->type = XML_RELAXNG_DATATYPE;
    def->name = type;
    def->ns = library;

    lib = (xmlRelaxNGTypeLibraryPtr)
        xmlHashLookup(xmlRelaxNGRegisteredTypes, library);
    if (lib == NULL) {
        xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_TYPE_LIB,
                   "Use of unregistered type library '%s'\n", library,
                   NULL);
        def->data = NULL;
    } else {
        def->data = lib;
        if (lib->have == NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_ERROR_TYPE_LIB,
                       "Internal error with type library '%s': no 'have'\n",
                       library, NULL);
        } else {
            tmp = lib->have(lib->data, def->name);
            if (tmp != 1) {
                xmlRngPErr(ctxt, node, XML_RNGP_TYPE_NOT_FOUND,
                           "Error type '%s' is not exported by type library '%s'\n",
                           def->name, library);
            } else
                if ((xmlStrEqual
                     (library,
                      BAD_CAST
                      "http://www.w3.org/2001/XMLSchema-datatypes"))
                    && ((xmlStrEqual(def->name, BAD_CAST "IDREF"))
                        || (xmlStrEqual(def->name, BAD_CAST "IDREFS")))) {
                ctxt->idref = 1;
            }
        }
    }
    content = node->children;

    /*
     * Handle optional params
     */
    while (content != NULL) {
        if (!xmlStrEqual(content->name, BAD_CAST "param"))
            break;
        if (xmlStrEqual(library,
                        BAD_CAST "http://relaxng.org/ns/structure/1.0")) {
            xmlRngPErr(ctxt, node, XML_RNGP_PARAM_FORBIDDEN,
                       "Type library '%s' does not allow type parameters\n",
                       library, NULL);
            content = content->next;
            while ((content != NULL) &&
                   (xmlStrEqual(content->name, BAD_CAST "param")))
                content = content->next;
        } else {
            param = xmlRelaxNGNewDefine(ctxt, node);
            if (param != NULL) {
                param->type = XML_RELAXNG_PARAM;
                param->name = xmlGetProp(content, BAD_CAST "name");
                if (param->name == NULL) {
                    xmlRngPErr(ctxt, node, XML_RNGP_PARAM_NAME_MISSING,
                               "param has no name\n", NULL, NULL);
                }
                param->value = xmlNodeGetContent(content);
                if (lastparam == NULL) {
                    def->attrs = lastparam = param;
                } else {
                    lastparam->next = param;
                    lastparam = param;
                }
                if (lib != NULL) {
                }
            }
            content = content->next;
        }
    }
    /*
     * Handle optional except
     */
    if ((content != NULL)
        && (xmlStrEqual(content->name, BAD_CAST "except"))) {
        xmlNodePtr child;
        xmlRelaxNGDefinePtr tmp2, last = NULL;

        except = xmlRelaxNGNewDefine(ctxt, node);
        if (except == NULL) {
            return (def);
        }
        except->type = XML_RELAXNG_EXCEPT;
        child = content->children;
	def->content = except;
        if (child == NULL) {
            xmlRngPErr(ctxt, content, XML_RNGP_EXCEPT_NO_CONTENT,
                       "except has no content\n", NULL, NULL);
        }
        while (child != NULL) {
            tmp2 = xmlRelaxNGParsePattern(ctxt, child);
            if (tmp2 != NULL) {
                if (last == NULL) {
                    except->content = last = tmp2;
                } else {
                    last->next = tmp2;
                    last = tmp2;
                }
            }
            child = child->next;
        }
        content = content->next;
    }
    /*
     * Check there is no unhandled data
     */
    if (content != NULL) {
        xmlRngPErr(ctxt, content, XML_RNGP_DATA_CONTENT,
                   "Element data has unexpected content %s\n",
                   content->name, NULL);
    }

    return (def);
}

static const xmlChar *invalidName = BAD_CAST "\1";

/**
 * xmlRelaxNGCompareNameClasses:
 * @defs1:  the first element/attribute defs
 * @defs2:  the second element/attribute defs
 * @name:  the restriction on the name
 * @ns:  the restriction on the namespace
 *
 * Compare the 2 lists of element definitions. The comparison is
 * that if both lists do not accept the same QNames, it returns 1
 * If the 2 lists can accept the same QName the comparison returns 0
 *
 * Returns 1 distinct, 0 if equal
 */
static int
xmlRelaxNGCompareNameClasses(xmlRelaxNGDefinePtr def1,
                             xmlRelaxNGDefinePtr def2)
{
    int ret = 1;
    xmlNode node;
    xmlNs ns;
    xmlRelaxNGValidCtxt ctxt;

    memset(&ctxt, 0, sizeof(xmlRelaxNGValidCtxt));

    ctxt.flags = FLAGS_IGNORABLE | FLAGS_NOERROR;

    if ((def1->type == XML_RELAXNG_ELEMENT) ||
        (def1->type == XML_RELAXNG_ATTRIBUTE)) {
        if (def2->type == XML_RELAXNG_TEXT)
            return (1);
        if (def1->name != NULL) {
            node.name = def1->name;
        } else {
            node.name = invalidName;
        }
        if (def1->ns != NULL) {
            if (def1->ns[0] == 0) {
                node.ns = NULL;
            } else {
	        node.ns = &ns;
                ns.href = def1->ns;
            }
        } else {
            node.ns = NULL;
        }
        if (xmlRelaxNGElementMatch(&ctxt, def2, &node)) {
            if (def1->nameClass != NULL) {
                ret = xmlRelaxNGCompareNameClasses(def1->nameClass, def2);
            } else {
                ret = 0;
            }
        } else {
            ret = 1;
        }
    } else if (def1->type == XML_RELAXNG_TEXT) {
        if (def2->type == XML_RELAXNG_TEXT)
            return (0);
        return (1);
    } else if (def1->type == XML_RELAXNG_EXCEPT) {
        ret = xmlRelaxNGCompareNameClasses(def1->content, def2);
	if (ret == 0)
	    ret = 1;
	else if (ret == 1)
	    ret = 0;
    } else {
        /* TODO */
        ret = 0;
    }
    if (ret == 0)
        return (ret);
    if ((def2->type == XML_RELAXNG_ELEMENT) ||
        (def2->type == XML_RELAXNG_ATTRIBUTE)) {
        if (def2->name != NULL) {
            node.name = def2->name;
        } else {
            node.name = invalidName;
        }
        node.ns = &ns;
        if (def2->ns != NULL) {
            if (def2->ns[0] == 0) {
                node.ns = NULL;
            } else {
                ns.href = def2->ns;
            }
        } else {
            ns.href = invalidName;
        }
        if (xmlRelaxNGElementMatch(&ctxt, def1, &node)) {
            if (def2->nameClass != NULL) {
                ret = xmlRelaxNGCompareNameClasses(def2->nameClass, def1);
            } else {
                ret = 0;
            }
        } else {
            ret = 1;
        }
    } else {
        /* TODO */
        ret = 0;
    }

    return (ret);
}

/**
 * xmlRelaxNGCompareElemDefLists:
 * @ctxt:  a Relax-NG parser context
 * @defs1:  the first list of element/attribute defs
 * @defs2:  the second list of element/attribute defs
 *
 * Compare the 2 lists of element or attribute definitions. The comparison
 * is that if both lists do not accept the same QNames, it returns 1
 * If the 2 lists can accept the same QName the comparison returns 0
 *
 * Returns 1 distinct, 0 if equal
 */
static int
xmlRelaxNGCompareElemDefLists(xmlRelaxNGParserCtxtPtr ctxt
                              ATTRIBUTE_UNUSED, xmlRelaxNGDefinePtr * def1,
                              xmlRelaxNGDefinePtr * def2)
{
    xmlRelaxNGDefinePtr *basedef2 = def2;

    if ((def1 == NULL) || (def2 == NULL))
        return (1);
    if ((*def1 == NULL) || (*def2 == NULL))
        return (1);
    while (*def1 != NULL) {
        while ((*def2) != NULL) {
            if (xmlRelaxNGCompareNameClasses(*def1, *def2) == 0)
                return (0);
            def2++;
        }
        def2 = basedef2;
        def1++;
    }
    return (1);
}

/**
 * xmlRelaxNGGenerateAttributes:
 * @ctxt:  a Relax-NG parser context
 * @def:  the definition definition
 *
 * Check if the definition can only generate attributes
 *
 * Returns 1 if yes, 0 if no and -1 in case of error.
 */
static int
xmlRelaxNGGenerateAttributes(xmlRelaxNGParserCtxtPtr ctxt,
                             xmlRelaxNGDefinePtr def)
{
    xmlRelaxNGDefinePtr parent, cur, tmp;

    /*
     * Don't run that check in case of error. Infinite recursion
     * becomes possible.
     */
    if (ctxt->nbErrors != 0)
        return (-1);

    parent = NULL;
    cur = def;
    while (cur != NULL) {
        if ((cur->type == XML_RELAXNG_ELEMENT) ||
            (cur->type == XML_RELAXNG_TEXT) ||
            (cur->type == XML_RELAXNG_DATATYPE) ||
            (cur->type == XML_RELAXNG_PARAM) ||
            (cur->type == XML_RELAXNG_LIST) ||
            (cur->type == XML_RELAXNG_VALUE) ||
            (cur->type == XML_RELAXNG_EMPTY))
            return (0);
        if ((cur->type == XML_RELAXNG_CHOICE) ||
            (cur->type == XML_RELAXNG_INTERLEAVE) ||
            (cur->type == XML_RELAXNG_GROUP) ||
            (cur->type == XML_RELAXNG_ONEORMORE) ||
            (cur->type == XML_RELAXNG_ZEROORMORE) ||
            (cur->type == XML_RELAXNG_OPTIONAL) ||
            (cur->type == XML_RELAXNG_PARENTREF) ||
            (cur->type == XML_RELAXNG_EXTERNALREF) ||
            (cur->type == XML_RELAXNG_REF) ||
            (cur->type == XML_RELAXNG_DEF)) {
            if (cur->content != NULL) {
                parent = cur;
                cur = cur->content;
                tmp = cur;
                while (tmp != NULL) {
                    tmp->parent = parent;
                    tmp = tmp->next;
                }
                continue;
            }
        }
        if (cur == def)
            break;
        if (cur->next != NULL) {
            cur = cur->next;
            continue;
        }
        do {
            cur = cur->parent;
            if (cur == NULL)
                break;
            if (cur == def)
                return (1);
            if (cur->next != NULL) {
                cur = cur->next;
                break;
            }
        } while (cur != NULL);
    }
    return (1);
}

/**
 * xmlRelaxNGGetElements:
 * @ctxt:  a Relax-NG parser context
 * @def:  the definition definition
 * @eora:  gather elements (0), attributes (1) or elements and text (2)
 *
 * Compute the list of top elements a definition can generate
 *
 * Returns a list of elements or NULL if none was found.
 */
static xmlRelaxNGDefinePtr *
xmlRelaxNGGetElements(xmlRelaxNGParserCtxtPtr ctxt,
                      xmlRelaxNGDefinePtr def, int eora)
{
    xmlRelaxNGDefinePtr *ret = NULL, parent, cur, tmp;
    int len = 0;
    int max = 0;

    /*
     * Don't run that check in case of error. Infinite recursion
     * becomes possible.
     */
    if (ctxt->nbErrors != 0)
        return (NULL);

    parent = NULL;
    cur = def;
    while (cur != NULL) {
        if (((eora == 0) && ((cur->type == XML_RELAXNG_ELEMENT) ||
                             (cur->type == XML_RELAXNG_TEXT))) ||
            ((eora == 1) && (cur->type == XML_RELAXNG_ATTRIBUTE)) ||
            ((eora == 2) && ((cur->type == XML_RELAXNG_DATATYPE) ||
	                     (cur->type == XML_RELAXNG_ELEMENT) ||
			     (cur->type == XML_RELAXNG_LIST) ||
                             (cur->type == XML_RELAXNG_TEXT) ||
			     (cur->type == XML_RELAXNG_VALUE)))) {
            if (ret == NULL) {
                max = 10;
                ret = (xmlRelaxNGDefinePtr *)
                    xmlMalloc((max + 1) * sizeof(xmlRelaxNGDefinePtr));
                if (ret == NULL) {
                    xmlRngPErrMemory(ctxt);
                    return (NULL);
                }
            } else if (max <= len) {
	        xmlRelaxNGDefinePtr *temp;

                max *= 2;
                temp = xmlRealloc(ret,
                               (max + 1) * sizeof(xmlRelaxNGDefinePtr));
                if (temp == NULL) {
                    xmlRngPErrMemory(ctxt);
		    xmlFree(ret);
                    return (NULL);
                }
		ret = temp;
            }
            ret[len++] = cur;
            ret[len] = NULL;
        } else if ((cur->type == XML_RELAXNG_CHOICE) ||
                   (cur->type == XML_RELAXNG_INTERLEAVE) ||
                   (cur->type == XML_RELAXNG_GROUP) ||
                   (cur->type == XML_RELAXNG_ONEORMORE) ||
                   (cur->type == XML_RELAXNG_ZEROORMORE) ||
                   (cur->type == XML_RELAXNG_OPTIONAL) ||
                   (cur->type == XML_RELAXNG_PARENTREF) ||
                   (cur->type == XML_RELAXNG_REF) ||
                   (cur->type == XML_RELAXNG_DEF) ||
		   (cur->type == XML_RELAXNG_EXTERNALREF)) {
            /*
             * Don't go within elements or attributes or string values.
             * Just gather the element top list
             */
            if (cur->content != NULL) {
                parent = cur;
                cur = cur->content;
                tmp = cur;
                while (tmp != NULL) {
                    tmp->parent = parent;
                    tmp = tmp->next;
                }
                continue;
            }
        }
        if (cur == def)
            break;
        if (cur->next != NULL) {
            cur = cur->next;
            continue;
        }
        do {
            cur = cur->parent;
            if (cur == NULL)
                break;
            if (cur == def)
                return (ret);
            if (cur->next != NULL) {
                cur = cur->next;
                break;
            }
        } while (cur != NULL);
    }
    return (ret);
}

/**
 * xmlRelaxNGCheckChoiceDeterminism:
 * @ctxt:  a Relax-NG parser context
 * @def:  the choice definition
 *
 * Also used to find indeterministic pattern in choice
 */
static void
xmlRelaxNGCheckChoiceDeterminism(xmlRelaxNGParserCtxtPtr ctxt,
                                 xmlRelaxNGDefinePtr def)
{
    xmlRelaxNGDefinePtr **list;
    xmlRelaxNGDefinePtr cur;
    int nbchild = 0, i, j, ret;
    int is_nullable = 0;
    int is_indeterminist = 0;
    xmlHashTablePtr triage = NULL;
    int is_triable = 1;

    if ((def == NULL) || (def->type != XML_RELAXNG_CHOICE))
        return;

    if (def->dflags & IS_PROCESSED)
        return;

    /*
     * Don't run that check in case of error. Infinite recursion
     * becomes possible.
     */
    if (ctxt->nbErrors != 0)
        return;

    is_nullable = xmlRelaxNGIsNullable(def);

    cur = def->content;
    while (cur != NULL) {
        nbchild++;
        cur = cur->next;
    }

    list = (xmlRelaxNGDefinePtr **) xmlMalloc(nbchild *
                                              sizeof(xmlRelaxNGDefinePtr
                                                     *));
    if (list == NULL) {
        xmlRngPErrMemory(ctxt);
        return;
    }
    i = 0;
    /*
     * a bit strong but safe
     */
    if (is_nullable == 0) {
        triage = xmlHashCreate(10);
    } else {
        is_triable = 0;
    }
    cur = def->content;
    while (cur != NULL) {
        list[i] = xmlRelaxNGGetElements(ctxt, cur, 0);
        if ((list[i] == NULL) || (list[i][0] == NULL)) {
            is_triable = 0;
        } else if (is_triable == 1) {
            xmlRelaxNGDefinePtr *tmp;
            int res;

            tmp = list[i];
            while ((*tmp != NULL) && (is_triable == 1)) {
                if ((*tmp)->type == XML_RELAXNG_TEXT) {
                    res = xmlHashAddEntry2(triage,
                                           BAD_CAST "#text", NULL,
                                           (void *) cur);
                    if (res != 0)
                        is_triable = -1;
                } else if (((*tmp)->type == XML_RELAXNG_ELEMENT) &&
                           ((*tmp)->name != NULL)) {
                    if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
                        res = xmlHashAddEntry2(triage,
                                               (*tmp)->name, NULL,
                                               (void *) cur);
                    else
                        res = xmlHashAddEntry2(triage,
                                               (*tmp)->name, (*tmp)->ns,
                                               (void *) cur);
                    if (res != 0)
                        is_triable = -1;
                } else if ((*tmp)->type == XML_RELAXNG_ELEMENT) {
                    if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
                        res = xmlHashAddEntry2(triage,
                                               BAD_CAST "#any", NULL,
                                               (void *) cur);
                    else
                        res = xmlHashAddEntry2(triage,
                                               BAD_CAST "#any", (*tmp)->ns,
                                               (void *) cur);
                    if (res != 0)
                        is_triable = -1;
                } else {
                    is_triable = -1;
                }
                tmp++;
            }
        }
        i++;
        cur = cur->next;
    }

    for (i = 0; i < nbchild; i++) {
        if (list[i] == NULL)
            continue;
        for (j = 0; j < i; j++) {
            if (list[j] == NULL)
                continue;
            ret = xmlRelaxNGCompareElemDefLists(ctxt, list[i], list[j]);
            if (ret == 0) {
                is_indeterminist = 1;
            }
        }
    }
    for (i = 0; i < nbchild; i++) {
        if (list[i] != NULL)
            xmlFree(list[i]);
    }

    xmlFree(list);
    if (is_indeterminist) {
        def->dflags |= IS_INDETERMINIST;
    }
    if (is_triable == 1) {
        def->dflags |= IS_TRIABLE;
        def->data = triage;
    } else if (triage != NULL) {
        xmlHashFree(triage, NULL);
    }
    def->dflags |= IS_PROCESSED;
}

/**
 * xmlRelaxNGCheckGroupAttrs:
 * @ctxt:  a Relax-NG parser context
 * @def:  the group definition
 *
 * Detects violations of rule 7.3
 */
static void
xmlRelaxNGCheckGroupAttrs(xmlRelaxNGParserCtxtPtr ctxt,
                          xmlRelaxNGDefinePtr def)
{
    xmlRelaxNGDefinePtr **list;
    xmlRelaxNGDefinePtr cur;
    int nbchild = 0, i, j, ret;

    if ((def == NULL) ||
        ((def->type != XML_RELAXNG_GROUP) &&
         (def->type != XML_RELAXNG_ELEMENT)))
        return;

    if (def->dflags & IS_PROCESSED)
        return;

    /*
     * Don't run that check in case of error. Infinite recursion
     * becomes possible.
     */
    if (ctxt->nbErrors != 0)
        return;

    cur = def->attrs;
    while (cur != NULL) {
        nbchild++;
        cur = cur->next;
    }
    cur = def->content;
    while (cur != NULL) {
        nbchild++;
        cur = cur->next;
    }

    list = (xmlRelaxNGDefinePtr **) xmlMalloc(nbchild *
                                              sizeof(xmlRelaxNGDefinePtr
                                                     *));
    if (list == NULL) {
        xmlRngPErrMemory(ctxt);
        return;
    }
    i = 0;
    cur = def->attrs;
    while (cur != NULL) {
        list[i] = xmlRelaxNGGetElements(ctxt, cur, 1);
        i++;
        cur = cur->next;
    }
    cur = def->content;
    while (cur != NULL) {
        list[i] = xmlRelaxNGGetElements(ctxt, cur, 1);
        i++;
        cur = cur->next;
    }

    for (i = 0; i < nbchild; i++) {
        if (list[i] == NULL)
            continue;
        for (j = 0; j < i; j++) {
            if (list[j] == NULL)
                continue;
            ret = xmlRelaxNGCompareElemDefLists(ctxt, list[i], list[j]);
            if (ret == 0) {
                xmlRngPErr(ctxt, def->node, XML_RNGP_GROUP_ATTR_CONFLICT,
                           "Attributes conflicts in group\n", NULL, NULL);
            }
        }
    }
    for (i = 0; i < nbchild; i++) {
        if (list[i] != NULL)
            xmlFree(list[i]);
    }

    xmlFree(list);
    def->dflags |= IS_PROCESSED;
}

/**
 * xmlRelaxNGComputeInterleaves:
 * @def:  the interleave definition
 * @ctxt:  a Relax-NG parser context
 * @name:  the definition name
 *
 * A lot of work for preprocessing interleave definitions
 * is potentially needed to get a decent execution speed at runtime
 *   - trying to get a total order on the element nodes generated
 *     by the interleaves, order the list of interleave definitions
 *     following that order.
 *   - if <text/> is used to handle mixed content, it is better to
 *     flag this in the define and simplify the runtime checking
 *     algorithm
 */
static void
xmlRelaxNGComputeInterleaves(void *payload, void *data,
                             const xmlChar * name ATTRIBUTE_UNUSED)
{
    xmlRelaxNGDefinePtr def = (xmlRelaxNGDefinePtr) payload;
    xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data;
    xmlRelaxNGDefinePtr cur, *tmp;

    xmlRelaxNGPartitionPtr partitions = NULL;
    xmlRelaxNGInterleaveGroupPtr *groups = NULL;
    xmlRelaxNGInterleaveGroupPtr group;
    int i, j, ret, res;
    int nbgroups = 0;
    int nbchild = 0;
    int is_mixed = 0;
    int is_determinist = 1;

    /*
     * Don't run that check in case of error. Infinite recursion
     * becomes possible.
     */
    if (ctxt->nbErrors != 0)
        return;

    cur = def->content;
    while (cur != NULL) {
        nbchild++;
        cur = cur->next;
    }

    groups = (xmlRelaxNGInterleaveGroupPtr *)
        xmlMalloc(nbchild * sizeof(xmlRelaxNGInterleaveGroupPtr));
    if (groups == NULL)
        goto error;
    cur = def->content;
    while (cur != NULL) {
        groups[nbgroups] = (xmlRelaxNGInterleaveGroupPtr)
            xmlMalloc(sizeof(xmlRelaxNGInterleaveGroup));
        if (groups[nbgroups] == NULL)
            goto error;
        if (cur->type == XML_RELAXNG_TEXT)
            is_mixed++;
        groups[nbgroups]->rule = cur;
        groups[nbgroups]->defs = xmlRelaxNGGetElements(ctxt, cur, 2);
        groups[nbgroups]->attrs = xmlRelaxNGGetElements(ctxt, cur, 1);
        nbgroups++;
        cur = cur->next;
    }

    /*
     * Let's check that all rules makes a partitions according to 7.4
     */
    partitions = (xmlRelaxNGPartitionPtr)
        xmlMalloc(sizeof(xmlRelaxNGPartition));
    if (partitions == NULL)
        goto error;
    memset(partitions, 0, sizeof(xmlRelaxNGPartition));
    partitions->nbgroups = nbgroups;
    partitions->triage = xmlHashCreate(nbgroups);
    for (i = 0; i < nbgroups; i++) {
        group = groups[i];
        for (j = i + 1; j < nbgroups; j++) {
            if (groups[j] == NULL)
                continue;

            ret = xmlRelaxNGCompareElemDefLists(ctxt, group->defs,
                                                groups[j]->defs);
            if (ret == 0) {
                xmlRngPErr(ctxt, def->node, XML_RNGP_ELEM_TEXT_CONFLICT,
                           "Element or text conflicts in interleave\n",
                           NULL, NULL);
            }
            ret = xmlRelaxNGCompareElemDefLists(ctxt, group->attrs,
                                                groups[j]->attrs);
            if (ret == 0) {
                xmlRngPErr(ctxt, def->node, XML_RNGP_ATTR_CONFLICT,
                           "Attributes conflicts in interleave\n", NULL,
                           NULL);
            }
        }
        tmp = group->defs;
        if ((tmp != NULL) && (*tmp != NULL)) {
            while (*tmp != NULL) {
                if ((*tmp)->type == XML_RELAXNG_TEXT) {
                    res = xmlHashAddEntry2(partitions->triage,
                                           BAD_CAST "#text", NULL,
                                           (void *) (ptrdiff_t) (i + 1));
                    if (res != 0)
                        is_determinist = -1;
                } else if (((*tmp)->type == XML_RELAXNG_ELEMENT) &&
                           ((*tmp)->name != NULL)) {
                    if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
                        res = xmlHashAddEntry2(partitions->triage,
                                               (*tmp)->name, NULL,
                                               (void *) (ptrdiff_t) (i + 1));
                    else
                        res = xmlHashAddEntry2(partitions->triage,
                                               (*tmp)->name, (*tmp)->ns,
                                               (void *) (ptrdiff_t) (i + 1));
                    if (res != 0)
                        is_determinist = -1;
                } else if ((*tmp)->type == XML_RELAXNG_ELEMENT) {
                    if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
                        res = xmlHashAddEntry2(partitions->triage,
                                               BAD_CAST "#any", NULL,
                                               (void *) (ptrdiff_t) (i + 1));
                    else
                        res = xmlHashAddEntry2(partitions->triage,
                                               BAD_CAST "#any", (*tmp)->ns,
                                               (void *) (ptrdiff_t) (i + 1));
                    if ((*tmp)->nameClass != NULL)
                        is_determinist = 2;
                    if (res != 0)
                        is_determinist = -1;
                } else {
                    is_determinist = -1;
                }
                tmp++;
            }
        } else {
            is_determinist = 0;
        }
    }
    partitions->groups = groups;

    /*
     * and save the partition list back in the def
     */
    def->data = partitions;
    if (is_mixed != 0)
        def->dflags |= IS_MIXED;
    if (is_determinist == 1)
        partitions->flags = IS_DETERMINIST;
    if (is_determinist == 2)
        partitions->flags = IS_DETERMINIST | IS_NEEDCHECK;
    return;

  error:
    xmlRngPErrMemory(ctxt);
    if (groups != NULL) {
        for (i = 0; i < nbgroups; i++)
            if (groups[i] != NULL) {
                if (groups[i]->defs != NULL)
                    xmlFree(groups[i]->defs);
                xmlFree(groups[i]);
            }
        xmlFree(groups);
    }
    xmlRelaxNGFreePartition(partitions);
}

/**
 * xmlRelaxNGParseInterleave:
 * @ctxt:  a Relax-NG parser context
 * @node:  the data node.
 *
 * parse the content of a RelaxNG interleave node.
 *
 * Returns the definition pointer or NULL in case of error
 */
static xmlRelaxNGDefinePtr
xmlRelaxNGParseInterleave(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
{
    xmlRelaxNGDefinePtr def = NULL;
    xmlRelaxNGDefinePtr last = NULL, cur;
    xmlNodePtr child;

    def = xmlRelaxNGNewDefine(ctxt, node);
    if (def == NULL) {
        return (NULL);
    }
    def->type = XML_RELAXNG_INTERLEAVE;

    if (ctxt->interleaves == NULL)
        ctxt->interleaves = xmlHashCreate(10);
    if (ctxt->interleaves == NULL) {
        xmlRngPErrMemory(ctxt);
    } else {
        char name[32];

        snprintf(name, 32, "interleave%d", ctxt->nbInterleaves++);
        if (xmlHashAddEntry(ctxt->interleaves, BAD_CAST name, def) < 0) {
            xmlRngPErr(ctxt, node, XML_RNGP_INTERLEAVE_ADD,
                       "Failed to add %s to hash table\n",
		       (const xmlChar *) name, NULL);
        }
    }
    child = node->children;
    if (child == NULL) {
        xmlRngPErr(ctxt, node, XML_RNGP_INTERLEAVE_NO_CONTENT,
                   "Element interleave is empty\n", NULL, NULL);
    }
    while (child != NULL) {
        if (IS_RELAXNG(child, "element")) {
            cur = xmlRelaxNGParseElement(ctxt, child);
        } else {
            cur = xmlRelaxNGParsePattern(ctxt, child);
        }
        if (cur != NULL) {
            cur->parent = def;
            if (last == NULL) {
                def->content = last = cur;
            } else {
                last->next = cur;
                last = cur;
            }
        }
        child = child->next;
    }

    return (def);
}

/**
 * xmlRelaxNGParseInclude:
 * @ctxt:  a Relax-NG parser context
 * @node:  the include node
 *
 * Integrate the content of an include node in the current grammar
 *
 * Returns 0 in case of success or -1 in case of error
 */
static int
xmlRelaxNGParseInclude(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
{
    xmlRelaxNGIncludePtr incl;
    xmlNodePtr root;
    int ret = 0, tmp;

    incl = node->psvi;
    if (incl == NULL) {
        xmlRngPErr(ctxt, node, XML_RNGP_INCLUDE_EMPTY,
                   "Include node has no data\n", NULL, NULL);
        return (-1);
    }
    root = xmlDocGetRootElement(incl->doc);
    if (root == NULL) {
        xmlRngPErr(ctxt, node, XML_RNGP_EMPTY, "Include document is empty\n",
                   NULL, NULL);
        return (-1);
    }
    if (!xmlStrEqual(root->name, BAD_CAST "grammar")) {
        xmlRngPErr(ctxt, node, XML_RNGP_GRAMMAR_MISSING,
                   "Include document root is not a grammar\n", NULL, NULL);
        return (-1);
    }

    /*
     * Merge the definition from both the include and the internal list
     */
    if (root->children != NULL) {
        tmp = xmlRelaxNGParseGrammarContent(ctxt, root->children);
        if (tmp != 0)
            ret = -1;
    }
    if (node->children != NULL) {
        tmp = xmlRelaxNGParseGrammarContent(ctxt, node->children);
        if (tmp != 0)
            ret = -1;
    }
    return (ret);
}

/**
 * xmlRelaxNGParseDefine:
 * @ctxt:  a Relax-NG parser context
 * @node:  the define node
 *
 * parse the content of a RelaxNG define element node.
 *
 * Returns 0 in case of success or -1 in case of error
 */
static int
xmlRelaxNGParseDefine(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
{
    xmlChar *name;
    int ret = 0, tmp;
    xmlRelaxNGDefinePtr def;
    const xmlChar *olddefine;

    name = xmlGetProp(node, BAD_CAST "name");
    if (name == NULL) {
        xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_NAME_MISSING,
                   "define has no name\n", NULL, NULL);
    } else {
        xmlRelaxNGNormExtSpace(name);
        if (xmlValidateNCName(name, 0)) {
            xmlRngPErr(ctxt, node, XML_RNGP_INVALID_DEFINE_NAME,
                       "define name '%s' is not an NCName\n", name, NULL);
        }
        def = xmlRelaxNGNewDefine(ctxt, node);
        if (def == NULL) {
            xmlFree(name);
            return (-1);
        }
        def->type = XML_RELAXNG_DEF;
        def->name = name;
        if (node->children == NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_EMPTY,
                       "define has no children\n", NULL, NULL);
        } else {
            olddefine = ctxt->define;
            ctxt->define = name;
            def->content =
                xmlRelaxNGParsePatterns(ctxt, node->children, 0);
            ctxt->define = olddefine;
        }
        if (ctxt->grammar->defs == NULL)
            ctxt->grammar->defs = xmlHashCreate(10);
        if (ctxt->grammar->defs == NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_CREATE_FAILED,
                       "Could not create definition hash\n", NULL, NULL);
            ret = -1;
        } else {
            tmp = xmlHashAddEntry(ctxt->grammar->defs, name, def);
            if (tmp < 0) {
                xmlRelaxNGDefinePtr prev;

                prev = xmlHashLookup(ctxt->grammar->defs, name);
                if (prev == NULL) {
                    xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_CREATE_FAILED,
                               "Internal error on define aggregation of %s\n",
                               name, NULL);
                    ret = -1;
                } else {
                    while (prev->nextHash != NULL)
                        prev = prev->nextHash;
                    prev->nextHash = def;
                }
            }
        }
    }
    return (ret);
}

/**
 * xmlRelaxNGParseImportRef:
 * @payload: the parser context
 * @data: the current grammar
 * @name: the reference name
 *
 * Import import one references into the current grammar
 */
static void
xmlRelaxNGParseImportRef(void *payload, void *data, const xmlChar *name) {
    xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data;
    xmlRelaxNGDefinePtr def = (xmlRelaxNGDefinePtr) payload;
    int tmp;

    def->dflags |= IS_EXTERNAL_REF;

    tmp = xmlHashAddEntry(ctxt->grammar->refs, name, def);
    if (tmp < 0) {
        xmlRelaxNGDefinePtr prev;

        prev = (xmlRelaxNGDefinePtr)
            xmlHashLookup(ctxt->grammar->refs, def->name);
        if (prev == NULL) {
            if (def->name != NULL) {
                xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
                           "Error refs definitions '%s'\n",
                           def->name, NULL);
            } else {
                xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
                           "Error refs definitions\n",
                           NULL, NULL);
            }
        } else {
            def->nextHash = prev->nextHash;
            prev->nextHash = def;
        }
    }
}

/**
 * xmlRelaxNGParseImportRefs:
 * @ctxt: the parser context
 * @grammar: the sub grammar
 *
 * Import references from the subgrammar into the current grammar
 *
 * Returns 0 in case of success, -1 in case of failure
 */
static int
xmlRelaxNGParseImportRefs(xmlRelaxNGParserCtxtPtr ctxt,
                          xmlRelaxNGGrammarPtr grammar) {
    if ((ctxt == NULL) || (grammar == NULL) || (ctxt->grammar == NULL))
        return(-1);
    if (grammar->refs == NULL)
        return(0);
    if (ctxt->grammar->refs == NULL)
        ctxt->grammar->refs = xmlHashCreate(10);
    if (ctxt->grammar->refs == NULL) {
        xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
                   "Could not create references hash\n", NULL, NULL);
        return(-1);
    }
    xmlHashScan(grammar->refs, xmlRelaxNGParseImportRef, ctxt);
    return(0);
}

/**
 * xmlRelaxNGProcessExternalRef:
 * @ctxt: the parser context
 * @node:  the externalRef node
 *
 * Process and compile an externalRef node
 *
 * Returns the xmlRelaxNGDefinePtr or NULL in case of error
 */
static xmlRelaxNGDefinePtr
xmlRelaxNGProcessExternalRef(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
{
    xmlRelaxNGDocumentPtr docu;
    xmlNodePtr root, tmp;
    xmlChar *ns;
    int newNs = 0, oldflags;
    xmlRelaxNGDefinePtr def;

    docu = node->psvi;
    if (docu != NULL) {
        def = xmlRelaxNGNewDefine(ctxt, node);
        if (def == NULL)
            return (NULL);
        def->type = XML_RELAXNG_EXTERNALREF;

        if (docu->content == NULL) {
            /*
             * Then do the parsing for good
             */
            root = xmlDocGetRootElement(docu->doc);
            if (root == NULL) {
                xmlRngPErr(ctxt, node, XML_RNGP_EXTERNALREF_EMTPY,
                           "xmlRelaxNGParse: %s is empty\n", ctxt->URL,
                           NULL);
                return (NULL);
            }
            /*
             * ns transmission rules
             */
            ns = xmlGetProp(root, BAD_CAST "ns");
            if (ns == NULL) {
                tmp = node;
                while ((tmp != NULL) && (tmp->type == XML_ELEMENT_NODE)) {
                    ns = xmlGetProp(tmp, BAD_CAST "ns");
                    if (ns != NULL) {
                        break;
                    }
                    tmp = tmp->parent;
                }
                if (ns != NULL) {
                    xmlSetProp(root, BAD_CAST "ns", ns);
                    newNs = 1;
                    xmlFree(ns);
                }
            } else {
                xmlFree(ns);
            }

            /*
             * Parsing to get a precompiled schemas.
             */
            oldflags = ctxt->flags;
            ctxt->flags |= XML_RELAXNG_IN_EXTERNALREF;
            docu->schema = xmlRelaxNGParseDocument(ctxt, root);
            ctxt->flags = oldflags;
            if ((docu->schema != NULL) &&
                (docu->schema->topgrammar != NULL)) {
                docu->content = docu->schema->topgrammar->start;
                if (docu->schema->topgrammar->refs)
                    xmlRelaxNGParseImportRefs(ctxt, docu->schema->topgrammar);
            }

            /*
             * the externalRef may be reused in a different ns context
             */
            if (newNs == 1) {
                xmlUnsetProp(root, BAD_CAST "ns");
            }
        }
        def->content = docu->content;
    } else {
        def = NULL;
    }
    return (def);
}

/**
 * xmlRelaxNGParsePattern:
 * @ctxt:  a Relax-NG parser context
 * @node:  the pattern node.
 *
 * parse the content of a RelaxNG pattern node.
 *
 * Returns the definition pointer or NULL in case of error or if no
 *     pattern is generated.
 */
static xmlRelaxNGDefinePtr
xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
{
    xmlRelaxNGDefinePtr def = NULL;

    if (node == NULL) {
        return (NULL);
    }
    if (IS_RELAXNG(node, "element")) {
        def = xmlRelaxNGParseElement(ctxt, node);
    } else if (IS_RELAXNG(node, "attribute")) {
        def = xmlRelaxNGParseAttribute(ctxt, node);
    } else if (IS_RELAXNG(node, "empty")) {
        def = xmlRelaxNGNewDefine(ctxt, node);
        if (def == NULL)
            return (NULL);
        def->type = XML_RELAXNG_EMPTY;
        if (node->children != NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_NOT_EMPTY,
                       "empty: had a child node\n", NULL, NULL);
        }
    } else if (IS_RELAXNG(node, "text")) {
        def = xmlRelaxNGNewDefine(ctxt, node);
        if (def == NULL)
            return (NULL);
        def->type = XML_RELAXNG_TEXT;
        if (node->children != NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_TEXT_HAS_CHILD,
                       "text: had a child node\n", NULL, NULL);
        }
    } else if (IS_RELAXNG(node, "zeroOrMore")) {
        def = xmlRelaxNGNewDefine(ctxt, node);
        if (def == NULL)
            return (NULL);
        def->type = XML_RELAXNG_ZEROORMORE;
        if (node->children == NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
                       "Element %s is empty\n", node->name, NULL);
        } else {
            def->content =
                xmlRelaxNGParsePatterns(ctxt, node->children, 1);
        }
    } else if (IS_RELAXNG(node, "oneOrMore")) {
        def = xmlRelaxNGNewDefine(ctxt, node);
        if (def == NULL)
            return (NULL);
        def->type = XML_RELAXNG_ONEORMORE;
        if (node->children == NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
                       "Element %s is empty\n", node->name, NULL);
        } else {
            def->content =
                xmlRelaxNGParsePatterns(ctxt, node->children, 1);
        }
    } else if (IS_RELAXNG(node, "optional")) {
        def = xmlRelaxNGNewDefine(ctxt, node);
        if (def == NULL)
            return (NULL);
        def->type = XML_RELAXNG_OPTIONAL;
        if (node->children == NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
                       "Element %s is empty\n", node->name, NULL);
        } else {
            def->content =
                xmlRelaxNGParsePatterns(ctxt, node->children, 1);
        }
    } else if (IS_RELAXNG(node, "choice")) {
        def = xmlRelaxNGNewDefine(ctxt, node);
        if (def == NULL)
            return (NULL);
        def->type = XML_RELAXNG_CHOICE;
        if (node->children == NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
                       "Element %s is empty\n", node->name, NULL);
        } else {
            def->content =
                xmlRelaxNGParsePatterns(ctxt, node->children, 0);
        }
    } else if (IS_RELAXNG(node, "group")) {
        def = xmlRelaxNGNewDefine(ctxt, node);
        if (def == NULL)
            return (NULL);
        def->type = XML_RELAXNG_GROUP;
        if (node->children == NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
                       "Element %s is empty\n", node->name, NULL);
        } else {
            def->content =
                xmlRelaxNGParsePatterns(ctxt, node->children, 0);
        }
    } else if (IS_RELAXNG(node, "ref")) {
        def = xmlRelaxNGNewDefine(ctxt, node);
        if (def == NULL)
            return (NULL);
        def->type = XML_RELAXNG_REF;
        def->name = xmlGetProp(node, BAD_CAST "name");
        if (def->name == NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_REF_NO_NAME, "ref has no name\n",
                       NULL, NULL);
        } else {
            xmlRelaxNGNormExtSpace(def->name);
            if (xmlValidateNCName(def->name, 0)) {
                xmlRngPErr(ctxt, node, XML_RNGP_REF_NAME_INVALID,
                           "ref name '%s' is not an NCName\n", def->name,
                           NULL);
            }
        }
        if (node->children != NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_REF_NOT_EMPTY, "ref is not empty\n",
                       NULL, NULL);
        }
        if (ctxt->grammar->refs == NULL)
            ctxt->grammar->refs = xmlHashCreate(10);
        if (ctxt->grammar->refs == NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_REF_CREATE_FAILED,
                       "Could not create references hash\n", NULL, NULL);
            def = NULL;
        } else {
            int tmp;

            tmp = xmlHashAddEntry(ctxt->grammar->refs, def->name, def);
            if (tmp < 0) {
                xmlRelaxNGDefinePtr prev;

                prev = (xmlRelaxNGDefinePtr)
                    xmlHashLookup(ctxt->grammar->refs, def->name);
                if (prev == NULL) {
                    if (def->name != NULL) {
		        xmlRngPErr(ctxt, node, XML_RNGP_REF_CREATE_FAILED,
				   "Error refs definitions '%s'\n",
				   def->name, NULL);
                    } else {
		        xmlRngPErr(ctxt, node, XML_RNGP_REF_CREATE_FAILED,
				   "Error refs definitions\n",
				   NULL, NULL);
                    }
                    def = NULL;
                } else {
                    def->nextHash = prev->nextHash;
                    prev->nextHash = def;
                }
            }
        }
    } else if (IS_RELAXNG(node, "data")) {
        def = xmlRelaxNGParseData(ctxt, node);
    } else if (IS_RELAXNG(node, "value")) {
        def = xmlRelaxNGParseValue(ctxt, node);
    } else if (IS_RELAXNG(node, "list")) {
        def = xmlRelaxNGNewDefine(ctxt, node);
        if (def == NULL)
            return (NULL);
        def->type = XML_RELAXNG_LIST;
        if (node->children == NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
                       "Element %s is empty\n", node->name, NULL);
        } else {
            def->content =
                xmlRelaxNGParsePatterns(ctxt, node->children, 0);
        }
    } else if (IS_RELAXNG(node, "interleave")) {
        def = xmlRelaxNGParseInterleave(ctxt, node);
    } else if (IS_RELAXNG(node, "externalRef")) {
        def = xmlRelaxNGProcessExternalRef(ctxt, node);
    } else if (IS_RELAXNG(node, "notAllowed")) {
        def = xmlRelaxNGNewDefine(ctxt, node);
        if (def == NULL)
            return (NULL);
        def->type = XML_RELAXNG_NOT_ALLOWED;
        if (node->children != NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_NOTALLOWED_NOT_EMPTY,
                       "xmlRelaxNGParse: notAllowed element is not empty\n",
                       NULL, NULL);
        }
    } else if (IS_RELAXNG(node, "grammar")) {
        xmlRelaxNGGrammarPtr grammar, old;
        xmlRelaxNGGrammarPtr oldparent;

        oldparent = ctxt->parentgrammar;
        old = ctxt->grammar;
        ctxt->parentgrammar = old;
        grammar = xmlRelaxNGParseGrammar(ctxt, node->children);
        if (old != NULL) {
            ctxt->grammar = old;
            ctxt->parentgrammar = oldparent;
#if 0
            if (grammar != NULL) {
                grammar->next = old->next;
                old->next = grammar;
            }
#endif
        }
        if (grammar != NULL)
            def = grammar->start;
        else
            def = NULL;
    } else if (IS_RELAXNG(node, "parentRef")) {
        if (ctxt->parentgrammar == NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_NO_PARENT,
                       "Use of parentRef without a parent grammar\n", NULL,
                       NULL);
            return (NULL);
        }
        def = xmlRelaxNGNewDefine(ctxt, node);
        if (def == NULL)
            return (NULL);
        def->type = XML_RELAXNG_PARENTREF;
        def->name = xmlGetProp(node, BAD_CAST "name");
        if (def->name == NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_NO_NAME,
                       "parentRef has no name\n", NULL, NULL);
        } else {
            xmlRelaxNGNormExtSpace(def->name);
            if (xmlValidateNCName(def->name, 0)) {
                xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_NAME_INVALID,
                           "parentRef name '%s' is not an NCName\n",
                           def->name, NULL);
            }
        }
        if (node->children != NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_NOT_EMPTY,
                       "parentRef is not empty\n", NULL, NULL);
        }
        if (ctxt->parentgrammar->refs == NULL)
            ctxt->parentgrammar->refs = xmlHashCreate(10);
        if (ctxt->parentgrammar->refs == NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_CREATE_FAILED,
                       "Could not create references hash\n", NULL, NULL);
            def = NULL;
        } else if (def->name != NULL) {
            int tmp;

            tmp =
                xmlHashAddEntry(ctxt->parentgrammar->refs, def->name, def);
            if (tmp < 0) {
                xmlRelaxNGDefinePtr prev;

                prev = (xmlRelaxNGDefinePtr)
                    xmlHashLookup(ctxt->parentgrammar->refs, def->name);
                if (prev == NULL) {
                    xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_CREATE_FAILED,
                               "Internal error parentRef definitions '%s'\n",
                               def->name, NULL);
                    def = NULL;
                } else {
                    def->nextHash = prev->nextHash;
                    prev->nextHash = def;
                }
            }
        }
    } else if (IS_RELAXNG(node, "mixed")) {
        if (node->children == NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT, "Mixed is empty\n",
                       NULL, NULL);
            def = NULL;
        } else {
            def = xmlRelaxNGParseInterleave(ctxt, node);
            if (def != NULL) {
                xmlRelaxNGDefinePtr tmp;

                if ((def->content != NULL) && (def->content->next != NULL)) {
                    tmp = xmlRelaxNGNewDefine(ctxt, node);
                    if (tmp != NULL) {
                        tmp->type = XML_RELAXNG_GROUP;
                        tmp->content = def->content;
                        def->content = tmp;
                    }
                }

                tmp = xmlRelaxNGNewDefine(ctxt, node);
                if (tmp == NULL)
                    return (def);
                tmp->type = XML_RELAXNG_TEXT;
                tmp->next = def->content;
                def->content = tmp;
            }
        }
    } else {
        xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_CONSTRUCT,
                   "Unexpected node %s is not a pattern\n", node->name,
                   NULL);
        def = NULL;
    }
    return (def);
}

/**
 * xmlRelaxNGParseAttribute:
 * @ctxt:  a Relax-NG parser context
 * @node:  the element node
 *
 * parse the content of a RelaxNG attribute node.
 *
 * Returns the definition pointer or NULL in case of error.
 */
static xmlRelaxNGDefinePtr
xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
{
    xmlRelaxNGDefinePtr ret, cur;
    xmlNodePtr child;
    int old_flags;

    ret = xmlRelaxNGNewDefine(ctxt, node);
    if (ret == NULL)
        return (NULL);
    ret->type = XML_RELAXNG_ATTRIBUTE;
    ret->parent = ctxt->def;
    child = node->children;
    if (child == NULL) {
        xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_EMPTY,
                   "xmlRelaxNGParseattribute: attribute has no children\n",
                   NULL, NULL);
        return (ret);
    }
    old_flags = ctxt->flags;
    ctxt->flags |= XML_RELAXNG_IN_ATTRIBUTE;
    cur = xmlRelaxNGParseNameClass(ctxt, child, ret);
    if (cur != NULL)
        child = child->next;

    if (child != NULL) {
        cur = xmlRelaxNGParsePattern(ctxt, child);
        if (cur != NULL) {
            switch (cur->type) {
                case XML_RELAXNG_EMPTY:
                case XML_RELAXNG_NOT_ALLOWED:
                case XML_RELAXNG_TEXT:
                case XML_RELAXNG_ELEMENT:
                case XML_RELAXNG_DATATYPE:
                case XML_RELAXNG_VALUE:
                case XML_RELAXNG_LIST:
                case XML_RELAXNG_REF:
                case XML_RELAXNG_PARENTREF:
                case XML_RELAXNG_EXTERNALREF:
                case XML_RELAXNG_DEF:
                case XML_RELAXNG_ONEORMORE:
                case XML_RELAXNG_ZEROORMORE:
                case XML_RELAXNG_OPTIONAL:
                case XML_RELAXNG_CHOICE:
                case XML_RELAXNG_GROUP:
                case XML_RELAXNG_INTERLEAVE:
                case XML_RELAXNG_ATTRIBUTE:
                    ret->content = cur;
                    cur->parent = ret;
                    break;
                case XML_RELAXNG_START:
                case XML_RELAXNG_PARAM:
                case XML_RELAXNG_EXCEPT:
                    xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_CONTENT,
                               "attribute has invalid content\n", NULL,
                               NULL);
                    break;
                case XML_RELAXNG_NOOP:
                    xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_NOOP,
                               "RNG Internal error, noop found in attribute\n",
                               NULL, NULL);
                    break;
            }
        }
        child = child->next;
    }
    if (child != NULL) {
        xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_CHILDREN,
                   "attribute has multiple children\n", NULL, NULL);
    }
    ctxt->flags = old_flags;
    return (ret);
}

/**
 * xmlRelaxNGParseExceptNameClass:
 * @ctxt:  a Relax-NG parser context
 * @node:  the except node
 * @attr:  1 if within an attribute, 0 if within an element
 *
 * parse the content of a RelaxNG nameClass node.
 *
 * Returns the definition pointer or NULL in case of error.
 */
static xmlRelaxNGDefinePtr
xmlRelaxNGParseExceptNameClass(xmlRelaxNGParserCtxtPtr ctxt,
                               xmlNodePtr node, int attr)
{
    xmlRelaxNGDefinePtr ret, cur, last = NULL;
    xmlNodePtr child;

    if (!IS_RELAXNG(node, "except")) {
        xmlRngPErr(ctxt, node, XML_RNGP_EXCEPT_MISSING,
                   "Expecting an except node\n", NULL, NULL);
        return (NULL);
    }
    if (node->next != NULL) {
        xmlRngPErr(ctxt, node, XML_RNGP_EXCEPT_MULTIPLE,
                   "exceptNameClass allows only a single except node\n",
                   NULL, NULL);
    }
    if (node->children == NULL) {
        xmlRngPErr(ctxt, node, XML_RNGP_EXCEPT_EMPTY, "except has no content\n",
                   NULL, NULL);
        return (NULL);
    }

    ret = xmlRelaxNGNewDefine(ctxt, node);
    if (ret == NULL)
        return (NULL);
    ret->type = XML_RELAXNG_EXCEPT;
    child = node->children;
    while (child != NULL) {
        cur = xmlRelaxNGNewDefine(ctxt, child);
        if (cur == NULL)
            break;
        if (attr)
            cur->type = XML_RELAXNG_ATTRIBUTE;
        else
            cur->type = XML_RELAXNG_ELEMENT;

        if (xmlRelaxNGParseNameClass(ctxt, child, cur) != NULL) {
            if (last == NULL) {
                ret->content = cur;
            } else {
                last->next = cur;
            }
            last = cur;
        }
        child = child->next;
    }

    return (ret);
}

/**
 * xmlRelaxNGParseNameClass:
 * @ctxt:  a Relax-NG parser context
 * @node:  the nameClass node
 * @def:  the current definition
 *
 * parse the content of a RelaxNG nameClass node.
 *
 * Returns the definition pointer or NULL in case of error.
 */
static xmlRelaxNGDefinePtr
xmlRelaxNGParseNameClass(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node,
                         xmlRelaxNGDefinePtr def)
{
    xmlRelaxNGDefinePtr ret, tmp;
    xmlChar *val;

    ret = def;
    if ((IS_RELAXNG(node, "name")) || (IS_RELAXNG(node, "anyName")) ||
        (IS_RELAXNG(node, "nsName"))) {
        if ((def->type != XML_RELAXNG_ELEMENT) &&
            (def->type != XML_RELAXNG_ATTRIBUTE)) {
            ret = xmlRelaxNGNewDefine(ctxt, node);
            if (ret == NULL)
                return (NULL);
            ret->parent = def;
            if (ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE)
                ret->type = XML_RELAXNG_ATTRIBUTE;
            else
                ret->type = XML_RELAXNG_ELEMENT;
        }
    }
    if (IS_RELAXNG(node, "name")) {
        val = xmlNodeGetContent(node);
        xmlRelaxNGNormExtSpace(val);
        if (xmlValidateNCName(val, 0)) {
	    if (node->parent != NULL)
		xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_NAME,
			   "Element %s name '%s' is not an NCName\n",
			   node->parent->name, val);
	    else
		xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_NAME,
			   "name '%s' is not an NCName\n",
			   val, NULL);
        }
        ret->name = val;
        val = xmlGetProp(node, BAD_CAST "ns");
        ret->ns = val;
        if ((ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE) &&
            (val != NULL) &&
            (xmlStrEqual(val, BAD_CAST "http://www.w3.org/2000/xmlns"))) {
	    xmlRngPErr(ctxt, node, XML_RNGP_XML_NS,
                        "Attribute with namespace '%s' is not allowed\n",
                        val, NULL);
        }
        if ((ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE) &&
            (val != NULL) &&
            (val[0] == 0) && (xmlStrEqual(ret->name, BAD_CAST "xmlns"))) {
	    xmlRngPErr(ctxt, node, XML_RNGP_XMLNS_NAME,
                       "Attribute with QName 'xmlns' is not allowed\n",
                       val, NULL);
        }
    } else if (IS_RELAXNG(node, "anyName")) {
        ret->name = NULL;
        ret->ns = NULL;
        if (node->children != NULL) {
            ret->nameClass =
                xmlRelaxNGParseExceptNameClass(ctxt, node->children,
                                               (def->type ==
                                                XML_RELAXNG_ATTRIBUTE));
        }
    } else if (IS_RELAXNG(node, "nsName")) {
        ret->name = NULL;
        ret->ns = xmlGetProp(node, BAD_CAST "ns");
        if (ret->ns == NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_NSNAME_NO_NS,
                       "nsName has no ns attribute\n", NULL, NULL);
        }
        if ((ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE) &&
            (ret->ns != NULL) &&
            (xmlStrEqual
             (ret->ns, BAD_CAST "http://www.w3.org/2000/xmlns"))) {
            xmlRngPErr(ctxt, node, XML_RNGP_XML_NS,
                       "Attribute with namespace '%s' is not allowed\n",
                       ret->ns, NULL);
        }
        if (node->children != NULL) {
            ret->nameClass =
                xmlRelaxNGParseExceptNameClass(ctxt, node->children,
                                               (def->type ==
                                                XML_RELAXNG_ATTRIBUTE));
        }
    } else if (IS_RELAXNG(node, "choice")) {
        xmlNodePtr child;
        xmlRelaxNGDefinePtr last = NULL;

        if (def->type == XML_RELAXNG_CHOICE) {
            ret = def;
        } else {
            ret = xmlRelaxNGNewDefine(ctxt, node);
            if (ret == NULL)
                return (NULL);
            ret->parent = def;
            ret->type = XML_RELAXNG_CHOICE;
        }

        if (node->children == NULL) {
            xmlRngPErr(ctxt, node, XML_RNGP_CHOICE_EMPTY,
                       "Element choice is empty\n", NULL, NULL);
        } else {

            child = node->children;
            while (child != NULL) {
                tmp = xmlRelaxNGParseNameClass(ctxt, child, ret);
                if (tmp != NULL) {
                    if (last == NULL) {
                        last = tmp;
                    } else if (tmp != ret) {
                        last->next = tmp;
                        last = tmp;
                    }
                }
                child = child->next;
            }
        }
    } else {
        xmlRngPErr(ctxt, node, XML_RNGP_CHOICE_CONTENT,
                   "expecting name, anyName, nsName or choice : got %s\n",
                   (node == NULL ? (const xmlChar *) "nothing" : node->name),
		   NULL);
        return (NULL);
    }
    if (ret != def) {
        if (def->nameClass == NULL) {
            def->nameClass = ret;
        } else {
            tmp = def->nameClass;
            while (tmp->next != NULL) {
                tmp = tmp->next;
            }
            tmp->next = ret;
        }
    }
    return (ret);
}

/**
 * xmlRelaxNGParseElement:
 * @ctxt:  a Relax-NG parser context
 * @node:  the element node
 *
 * parse the content of a RelaxNG element node.
 *
 * Returns the definition pointer or NULL in case of error.
 */
static xmlRelaxNGDefinePtr
xmlRelaxNGParseElement(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
{
    xmlRelaxNGDefinePtr ret, cur, last;
    xmlNodePtr child;
    const xmlChar *olddefine;

    ret = xmlRelaxNGNewDefine(ctxt, node);
    if (ret == NULL)
        return (NULL);
    ret->type = XML_RELAXNG_ELEMENT;
    ret->parent = ctxt->def;
    child = node->children;
    if (child == NULL) {
        xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_EMPTY,
                   "xmlRelaxNGParseElement: element has no children\n",
                   NULL, NULL);
        return (ret);
    }
    cur = xmlRelaxNGParseNameClass(ctxt, child, ret);
    if (cur != NULL)
        child = child->next;

    if (child == NULL) {
        xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_NO_CONTENT,
                   "xmlRelaxNGParseElement: element has no content\n",
                   NULL, NULL);
        return (ret);
    }
    olddefine = ctxt->define;
    ctxt->define = NULL;
    last = NULL;
    while (child != NULL) {
        cur = xmlRelaxNGParsePattern(ctxt, child);
        if (cur != NULL) {
            cur->parent = ret;
            switch (cur->type) {
                case XML_RELAXNG_EMPTY:
                case XML_RELAXNG_NOT_ALLOWED:
                case XML_RELAXNG_TEXT:
                case XML_RELAXNG_ELEMENT:
                case XML_RELAXNG_DATATYPE:
                case XML_RELAXNG_VALUE:
                case XML_RELAXNG_LIST:
                case XML_RELAXNG_REF:
                case XML_RELAXNG_PARENTREF:
                case XML_RELAXNG_EXTERNALREF:
                case XML_RELAXNG_DEF:
                case XML_RELAXNG_ZEROORMORE:
                case XML_RELAXNG_ONEORMORE:
                case XML_RELAXNG_OPTIONAL:
                case XML_RELAXNG_CHOICE:
                case XML_RELAXNG_GROUP:
                case XML_RELAXNG_INTERLEAVE:
                    if (last == NULL) {
                        ret->content = last = cur;
                    } else {
                        if ((last->type == XML_RELAXNG_ELEMENT) &&
                            (ret->content == last)) {
                            ret->content = xmlRelaxNGNewDefine(ctxt, node);
                            if (ret->content != NULL) {
                                ret->content->type = XML_RELAXNG_GROUP;
                                ret->content->content = last;
                            } else {
                                ret->content = last;
                            }
                        }
                        last->next = cur;
                        last = cur;
                    }
                    break;
                case XML_RELAXNG_ATTRIBUTE:
                    cur->next = ret->attrs;
                    ret->attrs = cur;
                    break;
                case XML_RELAXNG_START:
                    xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_CONTENT,
                               "RNG Internal error, start found in element\n",
                               NULL, NULL);
                    break;
                case XML_RELAXNG_PARAM:
                    xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_CONTENT,
                               "RNG Internal error, param found in element\n",
                               NULL, NULL);
                    break;
                case XML_RELAXNG_EXCEPT:
                    xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_CONTENT,
                               "RNG Internal error, except found in element\n",
                               NULL, NULL);
                    break;
                case XML_RELAXNG_NOOP:
                    xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_CONTENT,
                               "RNG Internal error, noop found in element\n",
                               NULL, NULL);
                    break;
            }
        }
        child = child->next;
    }
    ctxt->define = olddefine;
    return (ret);
}

/**
 * xmlRelaxNGParsePatterns:
 * @ctxt:  a Relax-NG parser context
 * @nodes:  list of nodes
 * @group:  use an implicit <group> for elements
 *
 * parse the content of a RelaxNG start node.
 *
 * Returns the definition pointer or NULL in case of error.
 */
static xmlRelaxNGDefinePtr
xmlRelaxNGParsePatterns(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes,
                        int group)
{
    xmlRelaxNGDefinePtr def = NULL, last = NULL, cur, parent;

    parent = ctxt->def;
    while (nodes != NULL) {
        if (IS_RELAXNG(nodes, "element")) {
            cur = xmlRelaxNGParseElement(ctxt, nodes);
            if (cur == NULL)
                return (NULL);
            if (def == NULL) {
                def = last = cur;
            } else {
                if ((group == 1) && (def->type == XML_RELAXNG_ELEMENT) &&
                    (def == last)) {
                    def = xmlRelaxNGNewDefine(ctxt, nodes);
                    if (def == NULL)
                        return (NULL);
                    def->type = XML_RELAXNG_GROUP;
                    def->content = last;
                }
                last->next = cur;
                last = cur;
            }
            cur->parent = parent;
        } else {
            cur = xmlRelaxNGParsePattern(ctxt, nodes);
            if (cur != NULL) {
                if (def == NULL) {
                    def = last = cur;
                } else {
                    last->next = cur;
                    last = cur;
                }
            }
        }
        nodes = nodes->next;
    }
    return (def);
}

/**
 * xmlRelaxNGParseStart:
 * @ctxt:  a Relax-NG parser context
 * @nodes:  start children nodes
 *
 * parse the content of a RelaxNG start node.
 *
 * Returns 0 in case of success, -1 in case of error
 */
static int
xmlRelaxNGParseStart(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes)
{
    int ret = 0;
    xmlRelaxNGDefinePtr def = NULL, last;

    if (nodes == NULL) {
        xmlRngPErr(ctxt, nodes, XML_RNGP_START_EMPTY, "start has no children\n",
                   NULL, NULL);
        return (-1);
    }
    if (IS_RELAXNG(nodes, "empty")) {
        def = xmlRelaxNGNewDefine(ctxt, nodes);
        if (def == NULL)
            return (-1);
        def->type = XML_RELAXNG_EMPTY;
        if (nodes->children != NULL) {
            xmlRngPErr(ctxt, nodes, XML_RNGP_EMPTY_CONTENT,
                       "element empty is not empty\n", NULL, NULL);
        }
    } else if (IS_RELAXNG(nodes, "notAllowed")) {
        def = xmlRelaxNGNewDefine(ctxt, nodes);
        if (def == NULL)
            return (-1);
        def->type = XML_RELAXNG_NOT_ALLOWED;
        if (nodes->children != NULL) {
            xmlRngPErr(ctxt, nodes, XML_RNGP_NOTALLOWED_NOT_EMPTY,
                       "element notAllowed is not empty\n", NULL, NULL);
        }
    } else {
        def = xmlRelaxNGParsePatterns(ctxt, nodes, 1);
    }
    if (ctxt->grammar->start != NULL) {
        last = ctxt->grammar->start;
        while (last->next != NULL)
            last = last->next;
        last->next = def;
    } else {
        ctxt->grammar->start = def;
    }
    nodes = nodes->next;
    if (nodes != NULL) {
        xmlRngPErr(ctxt, nodes, XML_RNGP_START_CONTENT,
                   "start more than one children\n", NULL, NULL);
        return (-1);
    }
    return (ret);
}

/**
 * xmlRelaxNGParseGrammarContent:
 * @ctxt:  a Relax-NG parser context
 * @nodes:  grammar children nodes
 *
 * parse the content of a RelaxNG grammar node.
 *
 * Returns 0 in case of success, -1 in case of error
 */
static int
xmlRelaxNGParseGrammarContent(xmlRelaxNGParserCtxtPtr ctxt,
                              xmlNodePtr nodes)
{
    int ret = 0, tmp;

    if (nodes == NULL) {
        xmlRngPErr(ctxt, nodes, XML_RNGP_GRAMMAR_EMPTY,
                   "grammar has no children\n", NULL, NULL);
        return (-1);
    }
    while (nodes != NULL) {
        if (IS_RELAXNG(nodes, "start")) {
            if (nodes->children == NULL) {
                xmlRngPErr(ctxt, nodes, XML_RNGP_START_EMPTY,
                           "start has no children\n", NULL, NULL);
            } else {
                tmp = xmlRelaxNGParseStart(ctxt, nodes->children);
                if (tmp != 0)
                    ret = -1;
            }
        } else if (IS_RELAXNG(nodes, "define")) {
            tmp = xmlRelaxNGParseDefine(ctxt, nodes);
            if (tmp != 0)
                ret = -1;
        } else if (IS_RELAXNG(nodes, "include")) {
            tmp = xmlRelaxNGParseInclude(ctxt, nodes);
            if (tmp != 0)
                ret = -1;
        } else {
            xmlRngPErr(ctxt, nodes, XML_RNGP_GRAMMAR_CONTENT,
                       "grammar has unexpected child %s\n", nodes->name,
                       NULL);
            ret = -1;
        }
        nodes = nodes->next;
    }
    return (ret);
}

/**
 * xmlRelaxNGCheckReference:
 * @ref:  the ref
 * @ctxt:  a Relax-NG parser context
 * @name:  the name associated to the defines
 *
 * Applies the 4.17. combine attribute rule for all the define
 * element of a given grammar using the same name.
 */
static void
xmlRelaxNGCheckReference(void *payload, void *data, const xmlChar * name)
{
    xmlRelaxNGDefinePtr ref = (xmlRelaxNGDefinePtr) payload;
    xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data;
    xmlRelaxNGGrammarPtr grammar;
    xmlRelaxNGDefinePtr def, cur;

    /*
     * Those rules don't apply to imported ref from xmlRelaxNGParseImportRef
     */
    if (ref->dflags & IS_EXTERNAL_REF)
        return;

    grammar = ctxt->grammar;
    if (grammar == NULL) {
        xmlRngPErr(ctxt, ref->node, XML_ERR_INTERNAL_ERROR,
                   "Internal error: no grammar in CheckReference %s\n",
                   name, NULL);
        return;
    }
    if (ref->content != NULL) {
        xmlRngPErr(ctxt, ref->node, XML_ERR_INTERNAL_ERROR,
                   "Internal error: reference has content in CheckReference %s\n",
                   name, NULL);
        return;
    }
    if (grammar->defs != NULL) {
        def = xmlHashLookup(grammar->defs, name);
        if (def != NULL) {
            cur = ref;
            while (cur != NULL) {
                cur->content = def;
                cur = cur->nextHash;
            }
        } else {
            xmlRngPErr(ctxt, ref->node, XML_RNGP_REF_NO_DEF,
                       "Reference %s has no matching definition\n", name,
                       NULL);
        }
    } else {
        xmlRngPErr(ctxt, ref->node, XML_RNGP_REF_NO_DEF,
                   "Reference %s has no matching definition\n", name,
                   NULL);
    }
}

/**
 * xmlRelaxNGCheckCombine:
 * @define:  the define(s) list
 * @ctxt:  a Relax-NG parser context
 * @name:  the name associated to the defines
 *
 * Applies the 4.17. combine attribute rule for all the define
 * element of a given grammar using the same name.
 */
static void
xmlRelaxNGCheckCombine(void *payload, void *data, const xmlChar * name)
{
    xmlRelaxNGDefinePtr define = (xmlRelaxNGDefinePtr) payload;
    xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data;
    xmlChar *combine;
    int choiceOrInterleave = -1;
    int missing = 0;
    xmlRelaxNGDefinePtr cur, last, tmp, tmp2;

    if (define->nextHash == NULL)
        return;
    cur = define;
    while (cur != NULL) {
        combine = xmlGetProp(cur->node, BAD_CAST "combine");
        if (combine != NULL) {
            if (xmlStrEqual(combine, BAD_CAST "choice")) {
                if (choiceOrInterleave == -1)
                    choiceOrInterleave = 1;
                else if (choiceOrInterleave == 0) {
                    xmlRngPErr(ctxt, define->node, XML_RNGP_DEF_CHOICE_AND_INTERLEAVE,
                               "Defines for %s use both 'choice' and 'interleave'\n",
                               name, NULL);
                }
            } else if (xmlStrEqual(combine, BAD_CAST "interleave")) {
                if (choiceOrInterleave == -1)
                    choiceOrInterleave = 0;
                else if (choiceOrInterleave == 1) {
                    xmlRngPErr(ctxt, define->node, XML_RNGP_DEF_CHOICE_AND_INTERLEAVE,
                               "Defines for %s use both 'choice' and 'interleave'\n",
                               name, NULL);
                }
            } else {
                xmlRngPErr(ctxt, define->node, XML_RNGP_UNKNOWN_COMBINE,
                           "Defines for %s use unknown combine value '%s''\n",
                           name, combine);
            }
            xmlFree(combine);
        } else {
            if (missing == 0)
                missing = 1;
            else {
                xmlRngPErr(ctxt, define->node, XML_RNGP_NEED_COMBINE,
                           "Some defines for %s needs the combine attribute\n",
                           name, NULL);
            }
        }

        cur = cur->nextHash;
    }
    if (choiceOrInterleave == -1)
        choiceOrInterleave = 0;
    cur = xmlRelaxNGNewDefine(ctxt, define->node);
    if (cur == NULL)
        return;
    if (choiceOrInterleave == 0)
        cur->type = XML_RELAXNG_INTERLEAVE;
    else
        cur->type = XML_RELAXNG_CHOICE;
    tmp = define;
    last = NULL;
    while (tmp != NULL) {
        if (tmp->content != NULL) {
            if (tmp->content->next != NULL) {
                /*
                 * we need first to create a wrapper.
                 */
                tmp2 = xmlRelaxNGNewDefine(ctxt, tmp->content->node);
                if (tmp2 == NULL)
                    break;
                tmp2->type = XML_RELAXNG_GROUP;
                tmp2->content = tmp->content;
            } else {
                tmp2 = tmp->content;
            }
            if (last == NULL) {
                cur->content = tmp2;
            } else {
                last->next = tmp2;
            }
            last = tmp2;
        }
        tmp->content = cur;
        tmp = tmp->nextHash;
    }
    define->content = cur;
    if (choiceOrInterleave == 0) {
        if (ctxt->interleaves == NULL)
            ctxt->interleaves = xmlHashCreate(10);
        if (ctxt->interleaves == NULL) {
            xmlRngPErr(ctxt, define->node, XML_RNGP_INTERLEAVE_CREATE_FAILED,
                       "Failed to create interleaves hash table\n", NULL,
                       NULL);
        } else {
            char tmpname[32];

            snprintf(tmpname, 32, "interleave%d", ctxt->nbInterleaves++);
            if (xmlHashAddEntry(ctxt->interleaves, BAD_CAST tmpname, cur) <
                0) {
                xmlRngPErr(ctxt, define->node, XML_RNGP_INTERLEAVE_CREATE_FAILED,
                           "Failed to add %s to hash table\n",
			   (const xmlChar *) tmpname, NULL);
            }
        }
    }
}

/**
 * xmlRelaxNGCombineStart:
 * @ctxt:  a Relax-NG parser context
 * @grammar:  the grammar
 *
 * Applies the 4.17. combine rule for all the start
 * element of a given grammar.
 */
static void
xmlRelaxNGCombineStart(xmlRelaxNGParserCtxtPtr ctxt,
                       xmlRelaxNGGrammarPtr grammar)
{
    xmlRelaxNGDefinePtr starts;
    xmlChar *combine;
    int choiceOrInterleave = -1;
    int missing = 0;
    xmlRelaxNGDefinePtr cur;

    starts = grammar->start;
    if ((starts == NULL) || (starts->next == NULL))
        return;
    cur = starts;
    while (cur != NULL) {
        if ((cur->node == NULL) || (cur->node->parent == NULL) ||
            (!xmlStrEqual(cur->node->parent->name, BAD_CAST "start"))) {
            combine = NULL;
            xmlRngPErr(ctxt, cur->node, XML_RNGP_START_MISSING,
                       "Internal error: start element not found\n", NULL,
                       NULL);
        } else {
            combine = xmlGetProp(cur->node->parent, BAD_CAST "combine");
        }

        if (combine != NULL) {
            if (xmlStrEqual(combine, BAD_CAST "choice")) {
                if (choiceOrInterleave == -1)
                    choiceOrInterleave = 1;
                else if (choiceOrInterleave == 0) {
                    xmlRngPErr(ctxt, cur->node, XML_RNGP_START_CHOICE_AND_INTERLEAVE,
                               "<start> use both 'choice' and 'interleave'\n",
                               NULL, NULL);
                }
            } else if (xmlStrEqual(combine, BAD_CAST "interleave")) {
                if (choiceOrInterleave == -1)
                    choiceOrInterleave = 0;
                else if (choiceOrInterleave == 1) {
                    xmlRngPErr(ctxt, cur->node, XML_RNGP_START_CHOICE_AND_INTERLEAVE,
                               "<start> use both 'choice' and 'interleave'\n",
                               NULL, NULL);
                }
            } else {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_UNKNOWN_COMBINE,
                           "<start> uses unknown combine value '%s''\n",
                           combine, NULL);
            }
            xmlFree(combine);
        } else {
            if (missing == 0)
                missing = 1;
            else {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_NEED_COMBINE,
                           "Some <start> element miss the combine attribute\n",
                           NULL, NULL);
            }
        }

        cur = cur->next;
    }
    if (choiceOrInterleave == -1)
        choiceOrInterleave = 0;
    cur = xmlRelaxNGNewDefine(ctxt, starts->node);
    if (cur == NULL)
        return;
    if (choiceOrInterleave == 0)
        cur->type = XML_RELAXNG_INTERLEAVE;
    else
        cur->type = XML_RELAXNG_CHOICE;
    cur->content = grammar->start;
    grammar->start = cur;
    if (choiceOrInterleave == 0) {
        if (ctxt->interleaves == NULL)
            ctxt->interleaves = xmlHashCreate(10);
        if (ctxt->interleaves == NULL) {
            xmlRngPErr(ctxt, cur->node, XML_RNGP_INTERLEAVE_CREATE_FAILED,
                       "Failed to create interleaves hash table\n", NULL,
                       NULL);
        } else {
            char tmpname[32];

            snprintf(tmpname, 32, "interleave%d", ctxt->nbInterleaves++);
            if (xmlHashAddEntry(ctxt->interleaves, BAD_CAST tmpname, cur) <
                0) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_INTERLEAVE_CREATE_FAILED,
                           "Failed to add %s to hash table\n",
			   (const xmlChar *) tmpname, NULL);
            }
        }
    }
}

/**
 * xmlRelaxNGCheckCycles:
 * @ctxt:  a Relax-NG parser context
 * @nodes:  grammar children nodes
 * @depth:  the counter
 *
 * Check for cycles.
 *
 * Returns 0 if check passed, and -1 in case of error
 */
static int
xmlRelaxNGCheckCycles(xmlRelaxNGParserCtxtPtr ctxt,
                      xmlRelaxNGDefinePtr cur, int depth)
{
    int ret = 0;

    while ((ret == 0) && (cur != NULL)) {
        if ((cur->type == XML_RELAXNG_REF) ||
            (cur->type == XML_RELAXNG_PARENTREF)) {
            if (cur->depth == -1) {
                cur->depth = depth;
                ret = xmlRelaxNGCheckCycles(ctxt, cur->content, depth);
                cur->depth = -2;
            } else if (depth == cur->depth) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_CYCLE,
                           "Detected a cycle in %s references\n",
                           cur->name, NULL);
                return (-1);
            }
        } else if (cur->type == XML_RELAXNG_ELEMENT) {
            ret = xmlRelaxNGCheckCycles(ctxt, cur->content, depth + 1);
        } else {
            ret = xmlRelaxNGCheckCycles(ctxt, cur->content, depth);
        }
        cur = cur->next;
    }
    return (ret);
}

/**
 * xmlRelaxNGTryUnlink:
 * @ctxt:  a Relax-NG parser context
 * @cur:  the definition to unlink
 * @parent:  the parent definition
 * @prev:  the previous sibling definition
 *
 * Try to unlink a definition. If not possible make it a NOOP
 *
 * Returns the new prev definition
 */
static xmlRelaxNGDefinePtr
xmlRelaxNGTryUnlink(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
                    xmlRelaxNGDefinePtr cur,
                    xmlRelaxNGDefinePtr parent, xmlRelaxNGDefinePtr prev)
{
    if (prev != NULL) {
        prev->next = cur->next;
    } else {
        if (parent != NULL) {
            if (parent->content == cur)
                parent->content = cur->next;
            else if (parent->attrs == cur)
                parent->attrs = cur->next;
            else if (parent->nameClass == cur)
                parent->nameClass = cur->next;
        } else {
            cur->type = XML_RELAXNG_NOOP;
            prev = cur;
        }
    }
    return (prev);
}

/**
 * xmlRelaxNGSimplify:
 * @ctxt:  a Relax-NG parser context
 * @nodes:  grammar children nodes
 *
 * Check for simplification of empty and notAllowed
 */
static void
xmlRelaxNGSimplify(xmlRelaxNGParserCtxtPtr ctxt,
                   xmlRelaxNGDefinePtr cur, xmlRelaxNGDefinePtr parent)
{
    xmlRelaxNGDefinePtr prev = NULL;

    while (cur != NULL) {
        if ((cur->type == XML_RELAXNG_REF) ||
            (cur->type == XML_RELAXNG_PARENTREF)) {
            if (cur->depth != -3) {
                cur->depth = -3;
                xmlRelaxNGSimplify(ctxt, cur->content, cur);
            }
        } else if (cur->type == XML_RELAXNG_NOT_ALLOWED) {
            cur->parent = parent;
            if ((parent != NULL) &&
                ((parent->type == XML_RELAXNG_ATTRIBUTE) ||
                 (parent->type == XML_RELAXNG_LIST) ||
                 (parent->type == XML_RELAXNG_GROUP) ||
                 (parent->type == XML_RELAXNG_INTERLEAVE) ||
                 (parent->type == XML_RELAXNG_ONEORMORE) ||
                 (parent->type == XML_RELAXNG_ZEROORMORE))) {
                parent->type = XML_RELAXNG_NOT_ALLOWED;
                break;
            }
            if ((parent != NULL) && (parent->type == XML_RELAXNG_CHOICE)) {
                prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
            } else
                prev = cur;
        } else if (cur->type == XML_RELAXNG_EMPTY) {
            cur->parent = parent;
            if ((parent != NULL) &&
                ((parent->type == XML_RELAXNG_ONEORMORE) ||
                 (parent->type == XML_RELAXNG_ZEROORMORE))) {
                parent->type = XML_RELAXNG_EMPTY;
                break;
            }
            if ((parent != NULL) &&
                ((parent->type == XML_RELAXNG_GROUP) ||
                 (parent->type == XML_RELAXNG_INTERLEAVE))) {
                prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
            } else
                prev = cur;
        } else {
            cur->parent = parent;
            if (cur->content != NULL)
                xmlRelaxNGSimplify(ctxt, cur->content, cur);
            if ((cur->type != XML_RELAXNG_VALUE) && (cur->attrs != NULL))
                xmlRelaxNGSimplify(ctxt, cur->attrs, cur);
            if (cur->nameClass != NULL)
                xmlRelaxNGSimplify(ctxt, cur->nameClass, cur);
            /*
             * On Elements, try to move attribute only generating rules on
             * the attrs rules.
             */
            if (cur->type == XML_RELAXNG_ELEMENT) {
                int attronly;
                xmlRelaxNGDefinePtr tmp, pre;

                while (cur->content != NULL) {
                    attronly =
                        xmlRelaxNGGenerateAttributes(ctxt, cur->content);
                    if (attronly == 1) {
                        /*
                         * migrate cur->content to attrs
                         */
                        tmp = cur->content;
                        cur->content = tmp->next;
                        tmp->next = cur->attrs;
                        cur->attrs = tmp;
                    } else {
                        /*
                         * cur->content can generate elements or text
                         */
                        break;
                    }
                }
                pre = cur->content;
                while ((pre != NULL) && (pre->next != NULL)) {
                    tmp = pre->next;
                    attronly = xmlRelaxNGGenerateAttributes(ctxt, tmp);
                    if (attronly == 1) {
                        /*
                         * migrate tmp to attrs
                         */
                        pre->next = tmp->next;
                        tmp->next = cur->attrs;
                        cur->attrs = tmp;
                    } else {
                        pre = tmp;
                    }
                }
            }
            /*
             * This may result in a simplification
             */
            if ((cur->type == XML_RELAXNG_GROUP) ||
                (cur->type == XML_RELAXNG_INTERLEAVE)) {
                if (cur->content == NULL)
                    cur->type = XML_RELAXNG_EMPTY;
                else if (cur->content->next == NULL) {
                    if ((parent == NULL) && (prev == NULL)) {
                        cur->type = XML_RELAXNG_NOOP;
                    } else if (prev == NULL) {
                        parent->content = cur->content;
                        cur->content->next = cur->next;
                        cur = cur->content;
                    } else {
                        cur->content->next = cur->next;
                        prev->next = cur->content;
                        cur = cur->content;
                    }
                }
            }
            /*
             * the current node may have been transformed back
             */
            if ((cur->type == XML_RELAXNG_EXCEPT) &&
                (cur->content != NULL) &&
                (cur->content->type == XML_RELAXNG_NOT_ALLOWED)) {
                prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
            } else if (cur->type == XML_RELAXNG_NOT_ALLOWED) {
                if ((parent != NULL) &&
                    ((parent->type == XML_RELAXNG_ATTRIBUTE) ||
                     (parent->type == XML_RELAXNG_LIST) ||
                     (parent->type == XML_RELAXNG_GROUP) ||
                     (parent->type == XML_RELAXNG_INTERLEAVE) ||
                     (parent->type == XML_RELAXNG_ONEORMORE) ||
                     (parent->type == XML_RELAXNG_ZEROORMORE))) {
                    parent->type = XML_RELAXNG_NOT_ALLOWED;
                    break;
                }
                if ((parent != NULL) &&
                    (parent->type == XML_RELAXNG_CHOICE)) {
                    prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
                } else
                    prev = cur;
            } else if (cur->type == XML_RELAXNG_EMPTY) {
                if ((parent != NULL) &&
                    ((parent->type == XML_RELAXNG_ONEORMORE) ||
                     (parent->type == XML_RELAXNG_ZEROORMORE))) {
                    parent->type = XML_RELAXNG_EMPTY;
                    break;
                }
                if ((parent != NULL) &&
                    ((parent->type == XML_RELAXNG_GROUP) ||
                     (parent->type == XML_RELAXNG_INTERLEAVE) ||
                     (parent->type == XML_RELAXNG_CHOICE))) {
                    prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
                } else
                    prev = cur;
            } else {
                prev = cur;
            }
        }
        cur = cur->next;
    }
}

/**
 * xmlRelaxNGGroupContentType:
 * @ct1:  the first content type
 * @ct2:  the second content type
 *
 * Try to group 2 content types
 *
 * Returns the content type
 */
static xmlRelaxNGContentType
xmlRelaxNGGroupContentType(xmlRelaxNGContentType ct1,
                           xmlRelaxNGContentType ct2)
{
    if ((ct1 == XML_RELAXNG_CONTENT_ERROR) ||
        (ct2 == XML_RELAXNG_CONTENT_ERROR))
        return (XML_RELAXNG_CONTENT_ERROR);
    if (ct1 == XML_RELAXNG_CONTENT_EMPTY)
        return (ct2);
    if (ct2 == XML_RELAXNG_CONTENT_EMPTY)
        return (ct1);
    if ((ct1 == XML_RELAXNG_CONTENT_COMPLEX) &&
        (ct2 == XML_RELAXNG_CONTENT_COMPLEX))
        return (XML_RELAXNG_CONTENT_COMPLEX);
    return (XML_RELAXNG_CONTENT_ERROR);
}

/**
 * xmlRelaxNGMaxContentType:
 * @ct1:  the first content type
 * @ct2:  the second content type
 *
 * Compute the max content-type
 *
 * Returns the content type
 */
static xmlRelaxNGContentType
xmlRelaxNGMaxContentType(xmlRelaxNGContentType ct1,
                         xmlRelaxNGContentType ct2)
{
    if ((ct1 == XML_RELAXNG_CONTENT_ERROR) ||
        (ct2 == XML_RELAXNG_CONTENT_ERROR))
        return (XML_RELAXNG_CONTENT_ERROR);
    if ((ct1 == XML_RELAXNG_CONTENT_SIMPLE) ||
        (ct2 == XML_RELAXNG_CONTENT_SIMPLE))
        return (XML_RELAXNG_CONTENT_SIMPLE);
    if ((ct1 == XML_RELAXNG_CONTENT_COMPLEX) ||
        (ct2 == XML_RELAXNG_CONTENT_COMPLEX))
        return (XML_RELAXNG_CONTENT_COMPLEX);
    return (XML_RELAXNG_CONTENT_EMPTY);
}

/**
 * xmlRelaxNGCheckRules:
 * @ctxt:  a Relax-NG parser context
 * @cur:  the current definition
 * @flags:  some accumulated flags
 * @ptype:  the parent type
 *
 * Check for rules in section 7.1 and 7.2
 *
 * Returns the content type of @cur
 */
static xmlRelaxNGContentType
xmlRelaxNGCheckRules(xmlRelaxNGParserCtxtPtr ctxt,
                     xmlRelaxNGDefinePtr cur, int flags,
                     xmlRelaxNGType ptype)
{
    int nflags;
    xmlRelaxNGContentType ret, tmp, val = XML_RELAXNG_CONTENT_EMPTY;

    while (cur != NULL) {
        ret = XML_RELAXNG_CONTENT_EMPTY;
        if ((cur->type == XML_RELAXNG_REF) ||
            (cur->type == XML_RELAXNG_PARENTREF)) {
           /*
            * This should actually be caught by list//element(ref) at the
            * element boundaries, c.f. Bug #159968 local refs are dropped
            * in step 4.19.
            */
#if 0
            if (flags & XML_RELAXNG_IN_LIST) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_REF,
                           "Found forbidden pattern list//ref\n", NULL,
                           NULL);
            }
#endif
            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_REF,
                           "Found forbidden pattern data/except//ref\n",
                           NULL, NULL);
            }
            if (cur->content == NULL) {
                if (cur->type == XML_RELAXNG_PARENTREF)
                    xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_NO_DEF,
                               "Internal found no define for parent refs\n",
                               NULL, NULL);
                else
                    xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_NO_DEF,
                               "Internal found no define for ref %s\n",
                               (cur->name ? cur->name: BAD_CAST "null"), NULL);
            }
            if (cur->depth > -4) {
                cur->depth = -4;
                ret = xmlRelaxNGCheckRules(ctxt, cur->content,
                                           flags, cur->type);
                cur->depth = ret - 15;
            } else if (cur->depth == -4) {
                ret = XML_RELAXNG_CONTENT_COMPLEX;
            } else {
                ret = (xmlRelaxNGContentType) (cur->depth + 15);
            }
        } else if (cur->type == XML_RELAXNG_ELEMENT) {
            /*
             * The 7.3 Attribute derivation rule for groups is plugged there
             */
            xmlRelaxNGCheckGroupAttrs(ctxt, cur);
            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_ELEM,
                           "Found forbidden pattern data/except//element(ref)\n",
                           NULL, NULL);
            }
            if (flags & XML_RELAXNG_IN_LIST) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_ELEM,
                           "Found forbidden pattern list//element(ref)\n",
                           NULL, NULL);
            }
            if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ATTR_ELEM,
                           "Found forbidden pattern attribute//element(ref)\n",
                           NULL, NULL);
            }
            if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ATTR_ELEM,
                           "Found forbidden pattern attribute//element(ref)\n",
                           NULL, NULL);
            }
            /*
             * reset since in the simple form elements are only child
             * of grammar/define
             */
            nflags = 0;
            ret =
                xmlRelaxNGCheckRules(ctxt, cur->attrs, nflags, cur->type);
            if (ret != XML_RELAXNG_CONTENT_EMPTY) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_ELEM_CONTENT_EMPTY,
                           "Element %s attributes have a content type error\n",
                           cur->name, NULL);
            }
            ret =
                xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
                                     cur->type);
            if (ret == XML_RELAXNG_CONTENT_ERROR) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_ELEM_CONTENT_ERROR,
                           "Element %s has a content type error\n",
                           cur->name, NULL);
            } else {
                ret = XML_RELAXNG_CONTENT_COMPLEX;
            }
        } else if (cur->type == XML_RELAXNG_ATTRIBUTE) {
            if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ATTR_ATTR,
                           "Found forbidden pattern attribute//attribute\n",
                           NULL, NULL);
            }
            if (flags & XML_RELAXNG_IN_LIST) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_ATTR,
                           "Found forbidden pattern list//attribute\n",
                           NULL, NULL);
            }
            if (flags & XML_RELAXNG_IN_OOMGROUP) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ONEMORE_GROUP_ATTR,
                           "Found forbidden pattern oneOrMore//group//attribute\n",
                           NULL, NULL);
            }
            if (flags & XML_RELAXNG_IN_OOMINTERLEAVE) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ONEMORE_INTERLEAVE_ATTR,
                           "Found forbidden pattern oneOrMore//interleave//attribute\n",
                           NULL, NULL);
            }
            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_ATTR,
                           "Found forbidden pattern data/except//attribute\n",
                           NULL, NULL);
            }
            if (flags & XML_RELAXNG_IN_START) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_ATTR,
                           "Found forbidden pattern start//attribute\n",
                           NULL, NULL);
            }
            if ((!(flags & XML_RELAXNG_IN_ONEORMORE))
                && cur->name == NULL
                /* following is checking alternative name class readiness
                   in case it went the "choice" route */
                && cur->nameClass == NULL) {
                if (cur->ns == NULL) {
                    xmlRngPErr(ctxt, cur->node, XML_RNGP_ANYNAME_ATTR_ANCESTOR,
                               "Found anyName attribute without oneOrMore ancestor\n",
                               NULL, NULL);
                } else {
                    xmlRngPErr(ctxt, cur->node, XML_RNGP_NSNAME_ATTR_ANCESTOR,
                               "Found nsName attribute without oneOrMore ancestor\n",
                               NULL, NULL);
                }
            }
            nflags = flags | XML_RELAXNG_IN_ATTRIBUTE;
            xmlRelaxNGCheckRules(ctxt, cur->content, nflags, cur->type);
            ret = XML_RELAXNG_CONTENT_EMPTY;
        } else if ((cur->type == XML_RELAXNG_ONEORMORE) ||
                   (cur->type == XML_RELAXNG_ZEROORMORE)) {
            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_ONEMORE,
                           "Found forbidden pattern data/except//oneOrMore\n",
                           NULL, NULL);
            }
            if (flags & XML_RELAXNG_IN_START) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_ONEMORE,
                           "Found forbidden pattern start//oneOrMore\n",
                           NULL, NULL);
            }
            nflags = flags | XML_RELAXNG_IN_ONEORMORE;
            ret =
                xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
                                     cur->type);
            ret = xmlRelaxNGGroupContentType(ret, ret);
        } else if (cur->type == XML_RELAXNG_LIST) {
            if (flags & XML_RELAXNG_IN_LIST) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_LIST,
                           "Found forbidden pattern list//list\n", NULL,
                           NULL);
            }
            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_LIST,
                           "Found forbidden pattern data/except//list\n",
                           NULL, NULL);
            }
            if (flags & XML_RELAXNG_IN_START) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_LIST,
                           "Found forbidden pattern start//list\n", NULL,
                           NULL);
            }
            nflags = flags | XML_RELAXNG_IN_LIST;
            ret =
                xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
                                     cur->type);
        } else if (cur->type == XML_RELAXNG_GROUP) {
            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_GROUP,
                           "Found forbidden pattern data/except//group\n",
                           NULL, NULL);
            }
            if (flags & XML_RELAXNG_IN_START) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_GROUP,
                           "Found forbidden pattern start//group\n", NULL,
                           NULL);
            }
            if (flags & XML_RELAXNG_IN_ONEORMORE)
                nflags = flags | XML_RELAXNG_IN_OOMGROUP;
            else
                nflags = flags;
            ret =
                xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
                                     cur->type);
            /*
             * The 7.3 Attribute derivation rule for groups is plugged there
             */
            xmlRelaxNGCheckGroupAttrs(ctxt, cur);
        } else if (cur->type == XML_RELAXNG_INTERLEAVE) {
            if (flags & XML_RELAXNG_IN_LIST) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_INTERLEAVE,
                           "Found forbidden pattern list//interleave\n",
                           NULL, NULL);
            }
            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_INTERLEAVE,
                           "Found forbidden pattern data/except//interleave\n",
                           NULL, NULL);
            }
            if (flags & XML_RELAXNG_IN_START) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_INTERLEAVE,
                           "Found forbidden pattern start//interleave\n",
                           NULL, NULL);
            }
            if (flags & XML_RELAXNG_IN_ONEORMORE)
                nflags = flags | XML_RELAXNG_IN_OOMINTERLEAVE;
            else
                nflags = flags;
            ret =
                xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
                                     cur->type);
        } else if (cur->type == XML_RELAXNG_EXCEPT) {
            if ((cur->parent != NULL) &&
                (cur->parent->type == XML_RELAXNG_DATATYPE))
                nflags = flags | XML_RELAXNG_IN_DATAEXCEPT;
            else
                nflags = flags;
            ret =
                xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
                                     cur->type);
        } else if (cur->type == XML_RELAXNG_DATATYPE) {
            if (flags & XML_RELAXNG_IN_START) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_DATA,
                           "Found forbidden pattern start//data\n", NULL,
                           NULL);
            }
            xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type);
            ret = XML_RELAXNG_CONTENT_SIMPLE;
        } else if (cur->type == XML_RELAXNG_VALUE) {
            if (flags & XML_RELAXNG_IN_START) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_VALUE,
                           "Found forbidden pattern start//value\n", NULL,
                           NULL);
            }
            xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type);
            ret = XML_RELAXNG_CONTENT_SIMPLE;
        } else if (cur->type == XML_RELAXNG_TEXT) {
            if (flags & XML_RELAXNG_IN_LIST) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_TEXT,
                           "Found forbidden pattern list//text\n", NULL,
                           NULL);
            }
            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_TEXT,
                           "Found forbidden pattern data/except//text\n",
                           NULL, NULL);
            }
            if (flags & XML_RELAXNG_IN_START) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_TEXT,
                           "Found forbidden pattern start//text\n", NULL,
                           NULL);
            }
            ret = XML_RELAXNG_CONTENT_COMPLEX;
        } else if (cur->type == XML_RELAXNG_EMPTY) {
            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_EMPTY,
                           "Found forbidden pattern data/except//empty\n",
                           NULL, NULL);
            }
            if (flags & XML_RELAXNG_IN_START) {
                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_EMPTY,
                           "Found forbidden pattern start//empty\n", NULL,
                           NULL);
            }
            ret = XML_RELAXNG_CONTENT_EMPTY;
        } else if (cur->type == XML_RELAXNG_CHOICE) {
            xmlRelaxNGCheckChoiceDeterminism(ctxt, cur);
            ret =
                xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type);
        } else {
            ret =
                xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type);
        }
        cur = cur->next;
        if (ptype == XML_RELAXNG_GROUP) {
            val = xmlRelaxNGGroupContentType(val, ret);
        } else if (ptype == XML_RELAXNG_INTERLEAVE) {
            /*
             * TODO: scan complain that tmp is never used, seems on purpose
             *       need double-checking
             */
            tmp = xmlRelaxNGGroupContentType(val, ret);
            if (tmp != XML_RELAXNG_CONTENT_ERROR)
                tmp = xmlRelaxNGMaxContentType(val, ret);
        } else if (ptype == XML_RELAXNG_CHOICE) {
            val = xmlRelaxNGMaxContentType(val, ret);
        } else if (ptype == XML_RELAXNG_LIST) {
            val = XML_RELAXNG_CONTENT_SIMPLE;
        } else if (ptype == XML_RELAXNG_EXCEPT) {
            if (ret == XML_RELAXNG_CONTENT_ERROR)
                val = XML_RELAXNG_CONTENT_ERROR;
            else
                val = XML_RELAXNG_CONTENT_SIMPLE;
        } else {
            val = xmlRelaxNGGroupContentType(val, ret);
        }

    }
    return (val);
}

/**
 * xmlRelaxNGParseGrammar:
 * @ctxt:  a Relax-NG parser context
 * @nodes:  grammar children nodes
 *
 * parse a Relax-NG <grammar> node
 *
 * Returns the internal xmlRelaxNGGrammarPtr built or
 *         NULL in case of error
 */
static xmlRelaxNGGrammarPtr
xmlRelaxNGParseGrammar(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes)
{
    xmlRelaxNGGrammarPtr ret, tmp, old;

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

    /*
     * Link the new grammar in the tree
     */
    ret->parent = ctxt->grammar;
    if (ctxt->grammar != NULL) {
        tmp = ctxt->grammar->children;
        if (tmp == NULL) {
            ctxt->grammar->children = ret;
        } else {
            while (tmp->next != NULL)
                tmp = tmp->next;
            tmp->next = ret;
        }
    }

    old = ctxt->grammar;
    ctxt->grammar = ret;
    xmlRelaxNGParseGrammarContent(ctxt, nodes);
    ctxt->grammar = ret;
    if (ctxt->grammar == NULL) {
        xmlRngPErr(ctxt, nodes, XML_RNGP_GRAMMAR_CONTENT,
                   "Failed to parse <grammar> content\n", NULL, NULL);
    } else if (ctxt->grammar->start == NULL) {
        xmlRngPErr(ctxt, nodes, XML_RNGP_GRAMMAR_NO_START,
                   "Element <grammar> has no <start>\n", NULL, NULL);
    }

    /*
     * Apply 4.17 merging rules to defines and starts
     */
    xmlRelaxNGCombineStart(ctxt, ret);
    if (ret->defs != NULL) {
        xmlHashScan(ret->defs, xmlRelaxNGCheckCombine, ctxt);
    }

    /*
     * link together defines and refs in this grammar
     */
    if (ret->refs != NULL) {
        xmlHashScan(ret->refs, xmlRelaxNGCheckReference, ctxt);
    }


    /* @@@@ */

    ctxt->grammar = old;
    return (ret);
}

/**
 * xmlRelaxNGParseDocument:
 * @ctxt:  a Relax-NG parser context
 * @node:  the root node of the RelaxNG schema
 *
 * parse a Relax-NG definition resource and build an internal
 * xmlRelaxNG structure which can be used to validate instances.
 *
 * Returns the internal XML RelaxNG structure built or
 *         NULL in case of error
 */
static xmlRelaxNGPtr
xmlRelaxNGParseDocument(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
{
    xmlRelaxNGPtr schema = NULL;
    const xmlChar *olddefine;
    xmlRelaxNGGrammarPtr old;

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

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

    olddefine = ctxt->define;
    ctxt->define = NULL;
    if (IS_RELAXNG(node, "grammar")) {
        schema->topgrammar = xmlRelaxNGParseGrammar(ctxt, node->children);
        if (schema->topgrammar == NULL) {
            xmlRelaxNGFree(schema);
            return (NULL);
        }
    } else {
        xmlRelaxNGGrammarPtr tmp, ret;

        schema->topgrammar = ret = xmlRelaxNGNewGrammar(ctxt);
        if (schema->topgrammar == NULL) {
            xmlRelaxNGFree(schema);
            return (NULL);
        }
        /*
         * Link the new grammar in the tree
         */
        ret->parent = ctxt->grammar;
        if (ctxt->grammar != NULL) {
            tmp = ctxt->grammar->children;
            if (tmp == NULL) {
                ctxt->grammar->children = ret;
            } else {
                while (tmp->next != NULL)
                    tmp = tmp->next;
                tmp->next = ret;
            }
        }
        old = ctxt->grammar;
        ctxt->grammar = ret;
        xmlRelaxNGParseStart(ctxt, node);
        if (old != NULL)
            ctxt->grammar = old;
    }
    ctxt->define = olddefine;
    if (schema->topgrammar->start != NULL) {
        xmlRelaxNGCheckCycles(ctxt, schema->topgrammar->start, 0);
        if ((ctxt->flags & XML_RELAXNG_IN_EXTERNALREF) == 0) {
            xmlRelaxNGSimplify(ctxt, schema->topgrammar->start, NULL);
            while ((schema->topgrammar->start != NULL) &&
                   (schema->topgrammar->start->type == XML_RELAXNG_NOOP) &&
                   (schema->topgrammar->start->next != NULL))
                schema->topgrammar->start =
                    schema->topgrammar->start->content;
            xmlRelaxNGCheckRules(ctxt, schema->topgrammar->start,
                                 XML_RELAXNG_IN_START, XML_RELAXNG_NOOP);
        }
    }

    return (schema);
}

/************************************************************************
 *									*
 *			Reading RelaxNGs				*
 *									*
 ************************************************************************/

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

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

    ret =
        (xmlRelaxNGParserCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGParserCtxt));
    if (ret == NULL) {
        xmlRngPErrMemory(NULL);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));
    ret->URL = xmlStrdup((const xmlChar *) URL);
    return (ret);
}

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

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

    ret =
        (xmlRelaxNGParserCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGParserCtxt));
    if (ret == NULL) {
        xmlRngPErrMemory(NULL);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));
    ret->buffer = buffer;
    ret->size = size;
    return (ret);
}

/**
 * xmlRelaxNGNewDocParserCtxt:
 * @doc:  a preparsed document tree
 *
 * Create an XML RelaxNGs parser context for that document.
 * Note: since the process of compiling a RelaxNG schemas modifies the
 *       document, the @doc parameter is duplicated internally.
 *
 * Returns the parser context or NULL in case of error
 */
xmlRelaxNGParserCtxtPtr
xmlRelaxNGNewDocParserCtxt(xmlDocPtr doc)
{
    xmlRelaxNGParserCtxtPtr ret;
    xmlDocPtr copy;

    if (doc == NULL)
        return (NULL);
    copy = xmlCopyDoc(doc, 1);
    if (copy == NULL)
        return (NULL);

    ret =
        (xmlRelaxNGParserCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGParserCtxt));
    if (ret == NULL) {
        xmlRngPErrMemory(NULL);
        xmlFreeDoc(copy);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));
    ret->document = copy;
    ret->freedoc = 1;
    ret->userData = xmlGenericErrorContext;
    return (ret);
}

/**
 * xmlRelaxNGFreeParserCtxt:
 * @ctxt:  the schema parser context
 *
 * Free the resources associated to the schema parser context
 */
void
xmlRelaxNGFreeParserCtxt(xmlRelaxNGParserCtxtPtr ctxt)
{
    if (ctxt == NULL)
        return;
    if (ctxt->URL != NULL)
        xmlFree(ctxt->URL);
    if (ctxt->doc != NULL)
        xmlRelaxNGFreeDocument(ctxt->doc);
    if (ctxt->interleaves != NULL)
        xmlHashFree(ctxt->interleaves, NULL);
    if (ctxt->documents != NULL)
        xmlRelaxNGFreeDocumentList(ctxt->documents);
    if (ctxt->includes != NULL)
        xmlRelaxNGFreeIncludeList(ctxt->includes);
    if (ctxt->docTab != NULL)
        xmlFree(ctxt->docTab);
    if (ctxt->incTab != NULL)
        xmlFree(ctxt->incTab);
    if (ctxt->defTab != NULL) {
        int i;

        for (i = 0; i < ctxt->defNr; i++)
            xmlRelaxNGFreeDefine(ctxt->defTab[i]);
        xmlFree(ctxt->defTab);
    }
    if ((ctxt->document != NULL) && (ctxt->freedoc))
        xmlFreeDoc(ctxt->document);
    xmlFree(ctxt);
}

/**
 * xmlRelaxNGNormExtSpace:
 * @value:  a value
 *
 * Removes the leading and ending spaces of the value
 * The string is modified "in situ"
 */
static void
xmlRelaxNGNormExtSpace(xmlChar * value)
{
    xmlChar *start = value;
    xmlChar *cur = value;

    if (value == NULL)
        return;

    while (IS_BLANK_CH(*cur))
        cur++;
    if (cur == start) {
        do {
            while ((*cur != 0) && (!IS_BLANK_CH(*cur)))
                cur++;
            if (*cur == 0)
                return;
            start = cur;
            while (IS_BLANK_CH(*cur))
                cur++;
            if (*cur == 0) {
                *start = 0;
                return;
            }
        } while (1);
    } else {
        do {
            while ((*cur != 0) && (!IS_BLANK_CH(*cur)))
                *start++ = *cur++;
            if (*cur == 0) {
                *start = 0;
                return;
            }
            /* don't try to normalize the inner spaces */
            while (IS_BLANK_CH(*cur))
                cur++;
            if (*cur == 0) {
                *start = 0;
                return;
            }
            *start++ = *cur++;
        } while (1);
    }
}

/**
 * xmlRelaxNGCleanupAttributes:
 * @ctxt:  a Relax-NG parser context
 * @node:  a Relax-NG node
 *
 * Check all the attributes on the given node
 */
static void
xmlRelaxNGCleanupAttributes(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
{
    xmlAttrPtr cur, next;

    cur = node->properties;
    while (cur != NULL) {
        next = cur->next;
        if ((cur->ns == NULL) ||
            (xmlStrEqual(cur->ns->href, xmlRelaxNGNs))) {
            if (xmlStrEqual(cur->name, BAD_CAST "name")) {
                if ((!xmlStrEqual(node->name, BAD_CAST "element")) &&
                    (!xmlStrEqual(node->name, BAD_CAST "attribute")) &&
                    (!xmlStrEqual(node->name, BAD_CAST "ref")) &&
                    (!xmlStrEqual(node->name, BAD_CAST "parentRef")) &&
                    (!xmlStrEqual(node->name, BAD_CAST "param")) &&
                    (!xmlStrEqual(node->name, BAD_CAST "define"))) {
                    xmlRngPErr(ctxt, node, XML_RNGP_FORBIDDEN_ATTRIBUTE,
                               "Attribute %s is not allowed on %s\n",
                               cur->name, node->name);
                }
            } else if (xmlStrEqual(cur->name, BAD_CAST "type")) {
                if ((!xmlStrEqual(node->name, BAD_CAST "value")) &&
                    (!xmlStrEqual(node->name, BAD_CAST "data"))) {
                    xmlRngPErr(ctxt, node, XML_RNGP_FORBIDDEN_ATTRIBUTE,
                               "Attribute %s is not allowed on %s\n",
                               cur->name, node->name);
                }
            } else if (xmlStrEqual(cur->name, BAD_CAST "href")) {
                if ((!xmlStrEqual(node->name, BAD_CAST "externalRef")) &&
                    (!xmlStrEqual(node->name, BAD_CAST "include"))) {
                    xmlRngPErr(ctxt, node, XML_RNGP_FORBIDDEN_ATTRIBUTE,
                               "Attribute %s is not allowed on %s\n",
                               cur->name, node->name);
                }
            } else if (xmlStrEqual(cur->name, BAD_CAST "combine")) {
                if ((!xmlStrEqual(node->name, BAD_CAST "start")) &&
                    (!xmlStrEqual(node->name, BAD_CAST "define"))) {
                    xmlRngPErr(ctxt, node, XML_RNGP_FORBIDDEN_ATTRIBUTE,
                               "Attribute %s is not allowed on %s\n",
                               cur->name, node->name);
                }
            } else if (xmlStrEqual(cur->name, BAD_CAST "datatypeLibrary")) {
                xmlChar *val;
                xmlURIPtr uri;

                val = xmlNodeListGetString(node->doc, cur->children, 1);
                if (val != NULL) {
                    if (val[0] != 0) {
                        uri = xmlParseURI((const char *) val);
                        if (uri == NULL) {
                            xmlRngPErr(ctxt, node, XML_RNGP_INVALID_URI,
                                       "Attribute %s contains invalid URI %s\n",
                                       cur->name, val);
                        } else {
                            if (uri->scheme == NULL) {
                                xmlRngPErr(ctxt, node, XML_RNGP_URI_NOT_ABSOLUTE,
                                           "Attribute %s URI %s is not absolute\n",
                                           cur->name, val);
                            }
                            if (uri->fragment != NULL) {
                                xmlRngPErr(ctxt, node, XML_RNGP_URI_FRAGMENT,
                                           "Attribute %s URI %s has a fragment ID\n",
                                           cur->name, val);
                            }
                            xmlFreeURI(uri);
                        }
                    }
                    xmlFree(val);
                }
            } else if (!xmlStrEqual(cur->name, BAD_CAST "ns")) {
                xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_ATTRIBUTE,
                           "Unknown attribute %s on %s\n", cur->name,
                           node->name);
            }
        }
        cur = next;
    }
}

/**
 * xmlRelaxNGCleanupTree:
 * @ctxt:  a Relax-NG parser context
 * @root:  an xmlNodePtr subtree
 *
 * Cleanup the subtree from unwanted nodes for parsing, resolve
 * Include and externalRef lookups.
 */
static void
xmlRelaxNGCleanupTree(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr root)
{
    xmlNodePtr cur, delete;

    delete = NULL;
    cur = root;
    while (cur != NULL) {
        if (delete != NULL) {
            xmlUnlinkNode(delete);
            xmlFreeNode(delete);
            delete = NULL;
        }
        if (cur->type == XML_ELEMENT_NODE) {
            /*
             * Simplification 4.1. Annotations
             */
            if ((cur->ns == NULL) ||
                (!xmlStrEqual(cur->ns->href, xmlRelaxNGNs))) {
                if ((cur->parent != NULL) &&
                    (cur->parent->type == XML_ELEMENT_NODE) &&
                    ((xmlStrEqual(cur->parent->name, BAD_CAST "name")) ||
                     (xmlStrEqual(cur->parent->name, BAD_CAST "value")) ||
                     (xmlStrEqual(cur->parent->name, BAD_CAST "param")))) {
                    xmlRngPErr(ctxt, cur, XML_RNGP_FOREIGN_ELEMENT,
                               "element %s doesn't allow foreign elements\n",
                               cur->parent->name, NULL);
                }
                delete = cur;
                goto skip_children;
            } else {
                xmlRelaxNGCleanupAttributes(ctxt, cur);
                if (xmlStrEqual(cur->name, BAD_CAST "externalRef")) {
                    xmlChar *href, *ns, *base, *URL;
                    xmlRelaxNGDocumentPtr docu;
                    xmlNodePtr tmp;
		    xmlURIPtr uri;

                    ns = xmlGetProp(cur, BAD_CAST "ns");
                    if (ns == NULL) {
                        tmp = cur->parent;
                        while ((tmp != NULL) &&
                               (tmp->type == XML_ELEMENT_NODE)) {
                            ns = xmlGetProp(tmp, BAD_CAST "ns");
                            if (ns != NULL)
                                break;
                            tmp = tmp->parent;
                        }
                    }
                    href = xmlGetProp(cur, BAD_CAST "href");
                    if (href == NULL) {
                        xmlRngPErr(ctxt, cur, XML_RNGP_MISSING_HREF,
                                   "xmlRelaxNGParse: externalRef has no href attribute\n",
                                   NULL, NULL);
                        if (ns != NULL)
                            xmlFree(ns);
                        delete = cur;
                        goto skip_children;
                    }
		    uri = xmlParseURI((const char *) href);
		    if (uri == NULL) {
                        xmlRngPErr(ctxt, cur, XML_RNGP_HREF_ERROR,
                                   "Incorrect URI for externalRef %s\n",
                                   href, NULL);
                        if (ns != NULL)
                            xmlFree(ns);
                        if (href != NULL)
                            xmlFree(href);
                        delete = cur;
                        goto skip_children;
		    }
		    if (uri->fragment != NULL) {
                        xmlRngPErr(ctxt, cur, XML_RNGP_HREF_ERROR,
			       "Fragment forbidden in URI for externalRef %s\n",
                                   href, NULL);
                        if (ns != NULL)
                            xmlFree(ns);
		        xmlFreeURI(uri);
                        if (href != NULL)
                            xmlFree(href);
                        delete = cur;
                        goto skip_children;
		    }
		    xmlFreeURI(uri);
                    base = xmlNodeGetBase(cur->doc, cur);
                    URL = xmlBuildURI(href, base);
                    if (URL == NULL) {
                        xmlRngPErr(ctxt, cur, XML_RNGP_HREF_ERROR,
                                   "Failed to compute URL for externalRef %s\n",
                                   href, NULL);
                        if (ns != NULL)
                            xmlFree(ns);
                        if (href != NULL)
                            xmlFree(href);
                        if (base != NULL)
                            xmlFree(base);
                        delete = cur;
                        goto skip_children;
                    }
                    if (href != NULL)
                        xmlFree(href);
                    if (base != NULL)
                        xmlFree(base);
                    docu = xmlRelaxNGLoadExternalRef(ctxt, URL, ns);
                    if (docu == NULL) {
                        xmlRngPErr(ctxt, cur, XML_RNGP_EXTERNAL_REF_FAILURE,
                                   "Failed to load externalRef %s\n", URL,
                                   NULL);
                        if (ns != NULL)
                            xmlFree(ns);
                        xmlFree(URL);
                        delete = cur;
                        goto skip_children;
                    }
                    if (ns != NULL)
                        xmlFree(ns);
                    xmlFree(URL);
                    cur->psvi = docu;
                } else if (xmlStrEqual(cur->name, BAD_CAST "include")) {
                    xmlChar *href, *ns, *base, *URL;
                    xmlRelaxNGIncludePtr incl;
                    xmlNodePtr tmp;

                    href = xmlGetProp(cur, BAD_CAST "href");
                    if (href == NULL) {
                        xmlRngPErr(ctxt, cur, XML_RNGP_MISSING_HREF,
                                   "xmlRelaxNGParse: include has no href attribute\n",
                                   NULL, NULL);
                        delete = cur;
                        goto skip_children;
                    }
                    base = xmlNodeGetBase(cur->doc, cur);
                    URL = xmlBuildURI(href, base);
                    if (URL == NULL) {
                        xmlRngPErr(ctxt, cur, XML_RNGP_HREF_ERROR,
                                   "Failed to compute URL for include %s\n",
                                   href, NULL);
                        if (href != NULL)
                            xmlFree(href);
                        if (base != NULL)
                            xmlFree(base);
                        delete = cur;
                        goto skip_children;
                    }
                    if (href != NULL)
                        xmlFree(href);
                    if (base != NULL)
                        xmlFree(base);
                    ns = xmlGetProp(cur, BAD_CAST "ns");
                    if (ns == NULL) {
                        tmp = cur->parent;
                        while ((tmp != NULL) &&
                               (tmp->type == XML_ELEMENT_NODE)) {
                            ns = xmlGetProp(tmp, BAD_CAST "ns");
                            if (ns != NULL)
                                break;
                            tmp = tmp->parent;
                        }
                    }
                    incl = xmlRelaxNGLoadInclude(ctxt, URL, cur, ns);
                    if (ns != NULL)
                        xmlFree(ns);
                    if (incl == NULL) {
                        xmlRngPErr(ctxt, cur, XML_RNGP_INCLUDE_FAILURE,
                                   "Failed to load include %s\n", URL,
                                   NULL);
                        xmlFree(URL);
                        delete = cur;
                        goto skip_children;
                    }
                    xmlFree(URL);
                    cur->psvi = incl;
                } else if ((xmlStrEqual(cur->name, BAD_CAST "element")) ||
                           (xmlStrEqual(cur->name, BAD_CAST "attribute")))
                {
                    xmlChar *name, *ns;
                    xmlNodePtr text = NULL;

                    /*
                     * Simplification 4.8. name attribute of element
                     * and attribute elements
                     */
                    name = xmlGetProp(cur, BAD_CAST "name");
                    if (name != NULL) {
                        if (cur->children == NULL) {
                            text =
                                xmlNewChild(cur, cur->ns, BAD_CAST "name",
                                            name);
                        } else {
                            xmlNodePtr node;

                            node = xmlNewDocNode(cur->doc, cur->ns,
			                         BAD_CAST "name", NULL);
                            if (node != NULL) {
                                xmlAddPrevSibling(cur->children, node);
                                text = xmlNewDocText(node->doc, name);
                                xmlAddChild(node, text);
                                text = node;
                            }
                        }
                        if (text == NULL) {
                            xmlRngPErr(ctxt, cur, XML_RNGP_CREATE_FAILURE,
                                       "Failed to create a name %s element\n",
                                       name, NULL);
                        }
                        xmlUnsetProp(cur, BAD_CAST "name");
                        xmlFree(name);
                        ns = xmlGetProp(cur, BAD_CAST "ns");
                        if (ns != NULL) {
                            if (text != NULL) {
                                xmlSetProp(text, BAD_CAST "ns", ns);
                                /* xmlUnsetProp(cur, BAD_CAST "ns"); */
                            }
                            xmlFree(ns);
                        } else if (xmlStrEqual(cur->name,
                                               BAD_CAST "attribute")) {
                            xmlSetProp(text, BAD_CAST "ns", BAD_CAST "");
                        }
                    }
                } else if ((xmlStrEqual(cur->name, BAD_CAST "name")) ||
                           (xmlStrEqual(cur->name, BAD_CAST "nsName")) ||
                           (xmlStrEqual(cur->name, BAD_CAST "value"))) {
                    /*
                     * Simplification 4.8. name attribute of element
                     * and attribute elements
                     */
                    if (xmlHasProp(cur, BAD_CAST "ns") == NULL) {
                        xmlNodePtr node;
                        xmlChar *ns = NULL;

                        node = cur->parent;
                        while ((node != NULL) &&
                               (node->type == XML_ELEMENT_NODE)) {
                            ns = xmlGetProp(node, BAD_CAST "ns");
                            if (ns != NULL) {
                                break;
                            }
                            node = node->parent;
                        }
                        if (ns == NULL) {
                            xmlSetProp(cur, BAD_CAST "ns", BAD_CAST "");
                        } else {
                            xmlSetProp(cur, BAD_CAST "ns", ns);
                            xmlFree(ns);
                        }
                    }
                    if (xmlStrEqual(cur->name, BAD_CAST "name")) {
                        xmlChar *name, *local, *prefix;

                        /*
                         * Simplification: 4.10. QNames
                         */
                        name = xmlNodeGetContent(cur);
                        if (name != NULL) {
                            local = xmlSplitQName2(name, &prefix);
                            if (local != NULL) {
                                xmlNsPtr ns;

                                ns = xmlSearchNs(cur->doc, cur, prefix);
                                if (ns == NULL) {
                                    xmlRngPErr(ctxt, cur,
                                               XML_RNGP_PREFIX_UNDEFINED,
                                               "xmlRelaxNGParse: no namespace for prefix %s\n",
                                               prefix, NULL);
                                } else {
                                    xmlSetProp(cur, BAD_CAST "ns",
                                               ns->href);
                                    xmlNodeSetContent(cur, local);
                                }
                                xmlFree(local);
                                xmlFree(prefix);
                            }
                            xmlFree(name);
                        }
                    }
                    /*
                     * 4.16
                     */
                    if (xmlStrEqual(cur->name, BAD_CAST "nsName")) {
                        if (ctxt->flags & XML_RELAXNG_IN_NSEXCEPT) {
                            xmlRngPErr(ctxt, cur,
                                       XML_RNGP_PAT_NSNAME_EXCEPT_NSNAME,
                                       "Found nsName/except//nsName forbidden construct\n",
                                       NULL, NULL);
                        }
                    }
                } else if ((xmlStrEqual(cur->name, BAD_CAST "except")) &&
                           (cur != root)) {
                    int oldflags = ctxt->flags;

                    /*
                     * 4.16
                     */
                    if ((cur->parent != NULL) &&
                        (xmlStrEqual
                         (cur->parent->name, BAD_CAST "anyName"))) {
                        ctxt->flags |= XML_RELAXNG_IN_ANYEXCEPT;
                        xmlRelaxNGCleanupTree(ctxt, cur);
                        ctxt->flags = oldflags;
                        goto skip_children;
                    } else if ((cur->parent != NULL) &&
                               (xmlStrEqual
                                (cur->parent->name, BAD_CAST "nsName"))) {
                        ctxt->flags |= XML_RELAXNG_IN_NSEXCEPT;
                        xmlRelaxNGCleanupTree(ctxt, cur);
                        ctxt->flags = oldflags;
                        goto skip_children;
                    }
                } else if (xmlStrEqual(cur->name, BAD_CAST "anyName")) {
                    /*
                     * 4.16
                     */
                    if (ctxt->flags & XML_RELAXNG_IN_ANYEXCEPT) {
                        xmlRngPErr(ctxt, cur,
                                   XML_RNGP_PAT_ANYNAME_EXCEPT_ANYNAME,
                                   "Found anyName/except//anyName forbidden construct\n",
                                   NULL, NULL);
                    } else if (ctxt->flags & XML_RELAXNG_IN_NSEXCEPT) {
                        xmlRngPErr(ctxt, cur,
                                   XML_RNGP_PAT_NSNAME_EXCEPT_ANYNAME,
                                   "Found nsName/except//anyName forbidden construct\n",
                                   NULL, NULL);
                    }
                }
                /*
                 * This is not an else since "include" is transformed
                 * into a div
                 */
                if (xmlStrEqual(cur->name, BAD_CAST "div")) {
                    xmlChar *ns;
                    xmlNodePtr child, ins, tmp;

                    /*
                     * implements rule 4.11
                     */

                    ns = xmlGetProp(cur, BAD_CAST "ns");

                    child = cur->children;
                    ins = cur;
                    while (child != NULL) {
                        if (ns != NULL) {
                            if (!xmlHasProp(child, BAD_CAST "ns")) {
                                xmlSetProp(child, BAD_CAST "ns", ns);
                            }
                        }
                        tmp = child->next;
                        xmlUnlinkNode(child);
                        ins = xmlAddNextSibling(ins, child);
                        child = tmp;
                    }
                    if (ns != NULL)
                        xmlFree(ns);
		    /*
		     * Since we are about to delete cur, if its nsDef is non-NULL we
		     * need to preserve it (it contains the ns definitions for the
		     * children we just moved).  We'll just stick it on to the end
		     * of cur->parent's list, since it's never going to be re-serialized
		     * (bug 143738).
		     */
		    if ((cur->nsDef != NULL) && (cur->parent != NULL)) {
			xmlNsPtr parDef = (xmlNsPtr)&cur->parent->nsDef;
			while (parDef->next != NULL)
			    parDef = parDef->next;
			parDef->next = cur->nsDef;
			cur->nsDef = NULL;
		    }
                    delete = cur;
                    goto skip_children;
                }
            }
        }
        /*
         * Simplification 4.2 whitespaces
         */
        else if ((cur->type == XML_TEXT_NODE) ||
                 (cur->type == XML_CDATA_SECTION_NODE)) {
            if (IS_BLANK_NODE(cur)) {
                if ((cur->parent != NULL) &&
		    (cur->parent->type == XML_ELEMENT_NODE)) {
                    if ((!xmlStrEqual(cur->parent->name, BAD_CAST "value"))
                        &&
                        (!xmlStrEqual
                         (cur->parent->name, BAD_CAST "param")))
                        delete = cur;
                } else {
                    delete = cur;
                    goto skip_children;
                }
            }
        } else {
            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;
    }
}

/**
 * xmlRelaxNGCleanupDoc:
 * @ctxt:  a Relax-NG parser context
 * @doc:  an xmldocPtr document pointer
 *
 * Cleanup the document from unwanted nodes for parsing, resolve
 * Include and externalRef lookups.
 *
 * Returns the cleaned up document or NULL in case of error
 */
static xmlDocPtr
xmlRelaxNGCleanupDoc(xmlRelaxNGParserCtxtPtr ctxt, xmlDocPtr doc)
{
    xmlNodePtr root;

    /*
     * Extract the root
     */
    root = xmlDocGetRootElement(doc);
    if (root == NULL) {
        xmlRngPErr(ctxt, (xmlNodePtr) doc, XML_RNGP_EMPTY, "xmlRelaxNGParse: %s is empty\n",
                   ctxt->URL, NULL);
        return (NULL);
    }
    xmlRelaxNGCleanupTree(ctxt, root);
    return (doc);
}

/**
 * xmlRelaxNGParse:
 * @ctxt:  a Relax-NG parser context
 *
 * parse a schema definition resource and build an internal
 * XML Schema structure which can be used to validate instances.
 *
 * Returns the internal XML RelaxNG structure built from the resource or
 *         NULL in case of error
 */
xmlRelaxNGPtr
xmlRelaxNGParse(xmlRelaxNGParserCtxtPtr ctxt)
{
    xmlRelaxNGPtr ret = NULL;
    xmlDocPtr doc;
    xmlNodePtr root;

    xmlRelaxNGInitTypes();

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

    /*
     * First step is to parse the input document into an DOM/Infoset
     */
    if (ctxt->URL != NULL) {
        doc = xmlRelaxReadFile(ctxt, (const char *) ctxt->URL);
        if (doc == NULL) {
            xmlRngPErr(ctxt, NULL, XML_RNGP_PARSE_ERROR,
                       "xmlRelaxNGParse: could not load %s\n", ctxt->URL,
                       NULL);
            return (NULL);
        }
    } else if (ctxt->buffer != NULL) {
        doc = xmlRelaxReadMemory(ctxt, ctxt->buffer, ctxt->size);
        if (doc == NULL) {
            xmlRngPErr(ctxt, NULL, XML_RNGP_PARSE_ERROR,
                       "xmlRelaxNGParse: could not parse schemas\n", NULL,
                       NULL);
            return (NULL);
        }
        doc->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
        ctxt->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
    } else if (ctxt->document != NULL) {
        doc = ctxt->document;
    } else {
        xmlRngPErr(ctxt, NULL, XML_RNGP_EMPTY,
                   "xmlRelaxNGParse: nothing to parse\n", NULL, NULL);
        return (NULL);
    }
    ctxt->document = doc;

    /*
     * Some preprocessing of the document content
     */
    doc = xmlRelaxNGCleanupDoc(ctxt, doc);
    if (doc == NULL) {
        xmlFreeDoc(ctxt->document);
        ctxt->document = NULL;
        return (NULL);
    }

    /*
     * Then do the parsing for good
     */
    root = xmlDocGetRootElement(doc);
    if (root == NULL) {
        xmlRngPErr(ctxt, (xmlNodePtr) doc,
	           XML_RNGP_EMPTY, "xmlRelaxNGParse: %s is empty\n",
                   (ctxt->URL ? ctxt->URL : BAD_CAST "schemas"), NULL);

        xmlFreeDoc(ctxt->document);
        ctxt->document = NULL;
        return (NULL);
    }
    ret = xmlRelaxNGParseDocument(ctxt, root);
    if (ret == NULL) {
        xmlFreeDoc(ctxt->document);
        ctxt->document = NULL;
        return (NULL);
    }

    /*
     * Check the ref/defines links
     */
    /*
     * try to preprocess interleaves
     */
    if (ctxt->interleaves != NULL) {
        xmlHashScan(ctxt->interleaves, xmlRelaxNGComputeInterleaves, ctxt);
    }

    /*
     * if there was a parsing error return NULL
     */
    if (ctxt->nbErrors > 0) {
        xmlRelaxNGFree(ret);
        ctxt->document = NULL;
        xmlFreeDoc(doc);
        return (NULL);
    }

    /*
     * try to compile (parts of) the schemas
     */
    if ((ret->topgrammar != NULL) && (ret->topgrammar->start != NULL)) {
        if (ret->topgrammar->start->type != XML_RELAXNG_START) {
            xmlRelaxNGDefinePtr def;

            def = xmlRelaxNGNewDefine(ctxt, NULL);
            if (def != NULL) {
                def->type = XML_RELAXNG_START;
                def->content = ret->topgrammar->start;
                ret->topgrammar->start = def;
            }
        }
        xmlRelaxNGTryCompile(ctxt, ret->topgrammar->start);
    }

    /*
     * Transfer the pointer for cleanup at the schema level.
     */
    ret->doc = doc;
    ctxt->document = NULL;
    ret->documents = ctxt->documents;
    ctxt->documents = NULL;

    ret->includes = ctxt->includes;
    ctxt->includes = NULL;
    ret->defNr = ctxt->defNr;
    ret->defTab = ctxt->defTab;
    ctxt->defTab = NULL;
    if (ctxt->idref == 1)
        ret->idref = 1;

    return (ret);
}

/**
 * xmlRelaxNGSetParserErrors:
 * @ctxt:  a Relax-NG validation context
 * @err:  the error callback
 * @warn:  the warning callback
 * @ctx:  contextual data for the callbacks
 *
 * DEPRECATED: Use xmlRelaxNGSetParserStructuredErrors.
 *
 * Set the callback functions used to handle errors for a validation context
 */
void
xmlRelaxNGSetParserErrors(xmlRelaxNGParserCtxtPtr ctxt,
                          xmlRelaxNGValidityErrorFunc err,
                          xmlRelaxNGValidityWarningFunc warn, void *ctx)
{
    if (ctxt == NULL)
        return;
    ctxt->error = err;
    ctxt->warning = warn;
    ctxt->serror = NULL;
    ctxt->userData = ctx;
}

/**
 * xmlRelaxNGGetParserErrors:
 * @ctxt:  a Relax-NG validation context
 * @err:  the error callback result
 * @warn:  the warning callback result
 * @ctx:  contextual data for the callbacks result
 *
 * Get the callback information used to handle errors for a validation context
 *
 * Returns -1 in case of failure, 0 otherwise.
 */
int
xmlRelaxNGGetParserErrors(xmlRelaxNGParserCtxtPtr ctxt,
                          xmlRelaxNGValidityErrorFunc * err,
                          xmlRelaxNGValidityWarningFunc * warn, void **ctx)
{
    if (ctxt == NULL)
        return (-1);
    if (err != NULL)
        *err = ctxt->error;
    if (warn != NULL)
        *warn = ctxt->warning;
    if (ctx != NULL)
        *ctx = ctxt->userData;
    return (0);
}

/**
 * xmlRelaxNGSetParserStructuredErrors:
 * @ctxt:  a Relax-NG parser context
 * @serror:  the error callback
 * @ctx:  contextual data for the callbacks
 *
 * Set the callback functions used to handle errors for a parsing context
 */
void
xmlRelaxNGSetParserStructuredErrors(xmlRelaxNGParserCtxtPtr ctxt,
				    xmlStructuredErrorFunc serror,
				    void *ctx)
{
    if (ctxt == NULL)
        return;
    ctxt->serror = serror;
    ctxt->error = NULL;
    ctxt->warning = NULL;
    ctxt->userData = ctx;
}

#ifdef LIBXML_OUTPUT_ENABLED

/************************************************************************
 *									*
 *			Dump back a compiled form			*
 *									*
 ************************************************************************/
static void xmlRelaxNGDumpDefine(FILE * output,
                                 xmlRelaxNGDefinePtr define);

/**
 * xmlRelaxNGDumpDefines:
 * @output:  the file output
 * @defines:  a list of define structures
 *
 * Dump a RelaxNG structure back
 */
static void
xmlRelaxNGDumpDefines(FILE * output, xmlRelaxNGDefinePtr defines)
{
    while (defines != NULL) {
        xmlRelaxNGDumpDefine(output, defines);
        defines = defines->next;
    }
}

/**
 * xmlRelaxNGDumpDefine:
 * @output:  the file output
 * @define:  a define structure
 *
 * Dump a RelaxNG structure back
 */
static void
xmlRelaxNGDumpDefine(FILE * output, xmlRelaxNGDefinePtr define)
{
    if (define == NULL)
        return;
    switch (define->type) {
        case XML_RELAXNG_EMPTY:
            fprintf(output, "<empty/>\n");
            break;
        case XML_RELAXNG_NOT_ALLOWED:
            fprintf(output, "<notAllowed/>\n");
            break;
        case XML_RELAXNG_TEXT:
            fprintf(output, "<text/>\n");
            break;
        case XML_RELAXNG_ELEMENT:
            fprintf(output, "<element>\n");
            if (define->name != NULL) {
                fprintf(output, "<name");
                if (define->ns != NULL)
                    fprintf(output, " ns=\"%s\"", define->ns);
                fprintf(output, ">%s</name>\n", define->name);
            }
            xmlRelaxNGDumpDefines(output, define->attrs);
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</element>\n");
            break;
        case XML_RELAXNG_LIST:
            fprintf(output, "<list>\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</list>\n");
            break;
        case XML_RELAXNG_ONEORMORE:
            fprintf(output, "<oneOrMore>\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</oneOrMore>\n");
            break;
        case XML_RELAXNG_ZEROORMORE:
            fprintf(output, "<zeroOrMore>\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</zeroOrMore>\n");
            break;
        case XML_RELAXNG_CHOICE:
            fprintf(output, "<choice>\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</choice>\n");
            break;
        case XML_RELAXNG_GROUP:
            fprintf(output, "<group>\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</group>\n");
            break;
        case XML_RELAXNG_INTERLEAVE:
            fprintf(output, "<interleave>\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</interleave>\n");
            break;
        case XML_RELAXNG_OPTIONAL:
            fprintf(output, "<optional>\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</optional>\n");
            break;
        case XML_RELAXNG_ATTRIBUTE:
            fprintf(output, "<attribute>\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</attribute>\n");
            break;
        case XML_RELAXNG_DEF:
            fprintf(output, "<define");
            if (define->name != NULL)
                fprintf(output, " name=\"%s\"", define->name);
            fprintf(output, ">\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</define>\n");
            break;
        case XML_RELAXNG_REF:
            fprintf(output, "<ref");
            if (define->name != NULL)
                fprintf(output, " name=\"%s\"", define->name);
            fprintf(output, ">\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</ref>\n");
            break;
        case XML_RELAXNG_PARENTREF:
            fprintf(output, "<parentRef");
            if (define->name != NULL)
                fprintf(output, " name=\"%s\"", define->name);
            fprintf(output, ">\n");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</parentRef>\n");
            break;
        case XML_RELAXNG_EXTERNALREF:
            fprintf(output, "<externalRef>");
            xmlRelaxNGDumpDefines(output, define->content);
            fprintf(output, "</externalRef>\n");
            break;
        case XML_RELAXNG_DATATYPE:
        case XML_RELAXNG_VALUE:
            /* TODO */
            break;
        case XML_RELAXNG_START:
        case XML_RELAXNG_EXCEPT:
        case XML_RELAXNG_PARAM:
            /* TODO */
            break;
        case XML_RELAXNG_NOOP:
            xmlRelaxNGDumpDefines(output, define->content);
            break;
    }
}

/**
 * xmlRelaxNGDumpGrammar:
 * @output:  the file output
 * @grammar:  a grammar structure
 * @top:  is this a top grammar
 *
 * Dump a RelaxNG structure back
 */
static void
xmlRelaxNGDumpGrammar(FILE * output, xmlRelaxNGGrammarPtr grammar, int top)
{
    if (grammar == NULL)
        return;

    fprintf(output, "<grammar");
    if (top)
        fprintf(output, " xmlns=\"http://relaxng.org/ns/structure/1.0\"");
    switch (grammar->combine) {
        case XML_RELAXNG_COMBINE_UNDEFINED:
            break;
        case XML_RELAXNG_COMBINE_CHOICE:
            fprintf(output, " combine=\"choice\"");
            break;
        case XML_RELAXNG_COMBINE_INTERLEAVE:
            fprintf(output, " combine=\"interleave\"");
            break;
        default:
            fprintf(output, " <!-- invalid combine value -->");
    }
    fprintf(output, ">\n");
    if (grammar->start == NULL) {
        fprintf(output, " <!-- grammar had no start -->");
    } else {
        fprintf(output, "<start>\n");
        xmlRelaxNGDumpDefine(output, grammar->start);
        fprintf(output, "</start>\n");
    }
    /* TODO ? Dump the defines ? */
    fprintf(output, "</grammar>\n");
}

/**
 * xmlRelaxNGDump:
 * @output:  the file output
 * @schema:  a schema structure
 *
 * Dump a RelaxNG structure back
 */
void
xmlRelaxNGDump(FILE * output, xmlRelaxNGPtr schema)
{
    if (output == NULL)
        return;
    if (schema == NULL) {
        fprintf(output, "RelaxNG empty or failed to compile\n");
        return;
    }
    fprintf(output, "RelaxNG: ");
    if (schema->doc == NULL) {
        fprintf(output, "no document\n");
    } else if (schema->doc->URL != NULL) {
        fprintf(output, "%s\n", schema->doc->URL);
    } else {
        fprintf(output, "\n");
    }
    if (schema->topgrammar == NULL) {
        fprintf(output, "RelaxNG has no top grammar\n");
        return;
    }
    xmlRelaxNGDumpGrammar(output, schema->topgrammar, 1);
}

/**
 * xmlRelaxNGDumpTree:
 * @output:  the file output
 * @schema:  a schema structure
 *
 * Dump the transformed RelaxNG tree.
 */
void
xmlRelaxNGDumpTree(FILE * output, xmlRelaxNGPtr schema)
{
    if (output == NULL)
        return;
    if (schema == NULL) {
        fprintf(output, "RelaxNG empty or failed to compile\n");
        return;
    }
    if (schema->doc == NULL) {
        fprintf(output, "no document\n");
    } else {
        xmlDocDump(output, schema->doc);
    }
}
#endif /* LIBXML_OUTPUT_ENABLED */

/************************************************************************
 *									*
 *		Validation of compiled content				*
 *									*
 ************************************************************************/
static int xmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt,
                                        xmlRelaxNGDefinePtr define);

/**
 * xmlRelaxNGValidateCompiledCallback:
 * @exec:  the regular expression instance
 * @token:  the token which matched
 * @transdata:  callback data, the define for the subelement if available
 @ @inputdata:  callback data, the Relax NG validation context
 *
 * Handle the callback and if needed validate the element children.
 */
static void
xmlRelaxNGValidateCompiledCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
                                   const xmlChar * token,
                                   void *transdata, void *inputdata)
{
    xmlRelaxNGValidCtxtPtr ctxt = (xmlRelaxNGValidCtxtPtr) inputdata;
    xmlRelaxNGDefinePtr define = (xmlRelaxNGDefinePtr) transdata;
    int ret;

    if (ctxt == NULL) {
        fprintf(stderr, "callback on %s missing context\n", token);
        return;
    }
    if (define == NULL) {
        if (token[0] == '#')
            return;
        fprintf(stderr, "callback on %s missing define\n", token);
        if ((ctxt != NULL) && (ctxt->errNo == XML_RELAXNG_OK))
            ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
        return;
    }
    if (define->type != XML_RELAXNG_ELEMENT) {
        fprintf(stderr, "callback on %s define is not element\n", token);
        if (ctxt->errNo == XML_RELAXNG_OK)
            ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
        return;
    }
    ret = xmlRelaxNGValidateDefinition(ctxt, define);
    if (ret != 0)
        ctxt->perr = ret;
}

/**
 * xmlRelaxNGValidateCompiledContent:
 * @ctxt:  the RelaxNG validation context
 * @regexp:  the regular expression as compiled
 * @content:  list of children to test against the regexp
 *
 * Validate the content model of an element or start using the regexp
 *
 * Returns 0 in case of success, -1 in case of error.
 */
static int
xmlRelaxNGValidateCompiledContent(xmlRelaxNGValidCtxtPtr ctxt,
                                  xmlRegexpPtr regexp, xmlNodePtr content)
{
    xmlRegExecCtxtPtr exec;
    xmlNodePtr cur;
    int ret = 0;
    int oldperr;

    if ((ctxt == NULL) || (regexp == NULL))
        return (-1);
    oldperr = ctxt->perr;
    exec = xmlRegNewExecCtxt(regexp,
                             xmlRelaxNGValidateCompiledCallback, ctxt);
    ctxt->perr = 0;
    cur = content;
    while (cur != NULL) {
        ctxt->state->seq = cur;
        switch (cur->type) {
            case XML_TEXT_NODE:
            case XML_CDATA_SECTION_NODE:
                if (xmlIsBlankNode(cur))
                    break;
                ret = xmlRegExecPushString(exec, BAD_CAST "#text", ctxt);
                if (ret < 0) {
                    VALID_ERR2(XML_RELAXNG_ERR_TEXTWRONG,
                               cur->parent->name);
                }
                break;
            case XML_ELEMENT_NODE:
                if (cur->ns != NULL) {
                    ret = xmlRegExecPushString2(exec, cur->name,
                                                cur->ns->href, ctxt);
                } else {
                    ret = xmlRegExecPushString(exec, cur->name, ctxt);
                }
                if (ret < 0) {
                    VALID_ERR2(XML_RELAXNG_ERR_ELEMWRONG, cur->name);
                }
                break;
            default:
                break;
        }
        if (ret < 0)
            break;
        /*
         * Switch to next element
         */
        cur = cur->next;
    }
    ret = xmlRegExecPushString(exec, NULL, NULL);
    if (ret == 1) {
        ret = 0;
        ctxt->state->seq = NULL;
    } else if (ret == 0) {
        /*
         * TODO: get some of the names needed to exit the current state of exec
         */
        VALID_ERR2(XML_RELAXNG_ERR_NOELEM, BAD_CAST "");
        ret = -1;
        if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
            xmlRelaxNGDumpValidError(ctxt);
    } else {
        ret = -1;
    }
    xmlRegFreeExecCtxt(exec);
    /*
     * There might be content model errors outside of the pure
     * regexp validation, e.g. for attribute values.
     */
    if ((ret == 0) && (ctxt->perr != 0)) {
        ret = ctxt->perr;
    }
    ctxt->perr = oldperr;
    return (ret);
}

/************************************************************************
 *									*
 *		Progressive validation of when possible			*
 *									*
 ************************************************************************/
static int xmlRelaxNGValidateAttributeList(xmlRelaxNGValidCtxtPtr ctxt,
                                           xmlRelaxNGDefinePtr defines);
static int xmlRelaxNGValidateElementEnd(xmlRelaxNGValidCtxtPtr ctxt,
                                        int dolog);
static void xmlRelaxNGLogBestError(xmlRelaxNGValidCtxtPtr ctxt);

/**
 * xmlRelaxNGElemPush:
 * @ctxt:  the validation context
 * @exec:  the regexp runtime for the new content model
 *
 * Push a new regexp for the current node content model on the stack
 *
 * Returns 0 in case of success and -1 in case of error.
 */
static int
xmlRelaxNGElemPush(xmlRelaxNGValidCtxtPtr ctxt, xmlRegExecCtxtPtr exec)
{
    if (ctxt->elemTab == NULL) {
        ctxt->elemMax = 10;
        ctxt->elemTab = (xmlRegExecCtxtPtr *) xmlMalloc(ctxt->elemMax *
                                                        sizeof
                                                        (xmlRegExecCtxtPtr));
        if (ctxt->elemTab == NULL) {
            xmlRngVErrMemory(ctxt);
            return (-1);
        }
    }
    if (ctxt->elemNr >= ctxt->elemMax) {
        ctxt->elemMax *= 2;
        ctxt->elemTab = (xmlRegExecCtxtPtr *) xmlRealloc(ctxt->elemTab,
                                                         ctxt->elemMax *
                                                         sizeof
                                                         (xmlRegExecCtxtPtr));
        if (ctxt->elemTab == NULL) {
            xmlRngVErrMemory(ctxt);
            return (-1);
        }
    }
    ctxt->elemTab[ctxt->elemNr++] = exec;
    ctxt->elem = exec;
    return (0);
}

/**
 * xmlRelaxNGElemPop:
 * @ctxt:  the validation context
 *
 * Pop the regexp of the current node content model from the stack
 *
 * Returns the exec or NULL if empty
 */
static xmlRegExecCtxtPtr
xmlRelaxNGElemPop(xmlRelaxNGValidCtxtPtr ctxt)
{
    xmlRegExecCtxtPtr ret;

    if (ctxt->elemNr <= 0)
        return (NULL);
    ctxt->elemNr--;
    ret = ctxt->elemTab[ctxt->elemNr];
    ctxt->elemTab[ctxt->elemNr] = NULL;
    if (ctxt->elemNr > 0)
        ctxt->elem = ctxt->elemTab[ctxt->elemNr - 1];
    else
        ctxt->elem = NULL;
    return (ret);
}

/**
 * xmlRelaxNGValidateProgressiveCallback:
 * @exec:  the regular expression instance
 * @token:  the token which matched
 * @transdata:  callback data, the define for the subelement if available
 @ @inputdata:  callback data, the Relax NG validation context
 *
 * Handle the callback and if needed validate the element children.
 * some of the in/out information are passed via the context in @inputdata.
 */
static void
xmlRelaxNGValidateProgressiveCallback(xmlRegExecCtxtPtr exec
                                      ATTRIBUTE_UNUSED,
                                      const xmlChar * token,
                                      void *transdata, void *inputdata)
{
    xmlRelaxNGValidCtxtPtr ctxt = (xmlRelaxNGValidCtxtPtr) inputdata;
    xmlRelaxNGDefinePtr define = (xmlRelaxNGDefinePtr) transdata;
    xmlRelaxNGValidStatePtr state, oldstate;
    xmlNodePtr node;
    int ret = 0, oldflags;

    if (ctxt == NULL) {
        fprintf(stderr, "callback on %s missing context\n", token);
        return;
    }
    node = ctxt->pnode;
    ctxt->pstate = 1;
    if (define == NULL) {
        if (token[0] == '#')
            return;
        fprintf(stderr, "callback on %s missing define\n", token);
        if ((ctxt != NULL) && (ctxt->errNo == XML_RELAXNG_OK))
            ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
        ctxt->pstate = -1;
        return;
    }
    if (define->type != XML_RELAXNG_ELEMENT) {
        fprintf(stderr, "callback on %s define is not element\n", token);
        if (ctxt->errNo == XML_RELAXNG_OK)
            ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
        ctxt->pstate = -1;
        return;
    }
    if (node->type != XML_ELEMENT_NODE) {
        VALID_ERR(XML_RELAXNG_ERR_NOTELEM);
        if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
            xmlRelaxNGDumpValidError(ctxt);
        ctxt->pstate = -1;
        return;
    }
    if (define->contModel == NULL) {
        /*
         * this node cannot be validated in a streamable fashion
         */
        ctxt->pstate = 0;
        ctxt->pdef = define;
        return;
    }
    exec = xmlRegNewExecCtxt(define->contModel,
                             xmlRelaxNGValidateProgressiveCallback, ctxt);
    if (exec == NULL) {
        ctxt->pstate = -1;
        return;
    }
    xmlRelaxNGElemPush(ctxt, exec);

    /*
     * Validate the attributes part of the content.
     */
    state = xmlRelaxNGNewValidState(ctxt, node);
    if (state == NULL) {
        ctxt->pstate = -1;
        return;
    }
    oldstate = ctxt->state;
    ctxt->state = state;
    if (define->attrs != NULL) {
        ret = xmlRelaxNGValidateAttributeList(ctxt, define->attrs);
        if (ret != 0) {
            ctxt->pstate = -1;
            VALID_ERR2(XML_RELAXNG_ERR_ATTRVALID, node->name);
        }
    }
    if (ctxt->state != NULL) {
        ctxt->state->seq = NULL;
        ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
        if (ret != 0) {
            ctxt->pstate = -1;
        }
        xmlRelaxNGFreeValidState(ctxt, ctxt->state);
    } else if (ctxt->states != NULL) {
        int tmp = -1, i;

        oldflags = ctxt->flags;

        for (i = 0; i < ctxt->states->nbState; i++) {
            state = ctxt->states->tabState[i];
            ctxt->state = state;
            ctxt->state->seq = NULL;

            if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
                tmp = 0;
                break;
            }
        }
        if (tmp != 0) {
            /*
             * validation error, log the message for the "best" one
             */
            ctxt->flags |= FLAGS_IGNORABLE;
            xmlRelaxNGLogBestError(ctxt);
        }
        for (i = 0; i < ctxt->states->nbState; i++) {
            xmlRelaxNGFreeValidState(ctxt, ctxt->states->tabState[i]);
        }
        xmlRelaxNGFreeStates(ctxt, ctxt->states);
        ctxt->states = NULL;
        if ((ret == 0) && (tmp == -1))
            ctxt->pstate = -1;
        ctxt->flags = oldflags;
    }
    if (ctxt->pstate == -1) {
        if ((ctxt->flags & FLAGS_IGNORABLE) == 0) {
            xmlRelaxNGDumpValidError(ctxt);
        }
    }
    ctxt->state = oldstate;
}

/**
 * xmlRelaxNGValidatePushElement:
 * @ctxt:  the validation context
 * @doc:  a document instance
 * @elem:  an element instance
 *
 * Push a new element start on the RelaxNG validation stack.
 *
 * returns 1 if no validation problem was found or 0 if validating the
 *         element requires a full node, and -1 in case of error.
 */
int
xmlRelaxNGValidatePushElement(xmlRelaxNGValidCtxtPtr ctxt,
                              xmlDocPtr doc ATTRIBUTE_UNUSED,
                              xmlNodePtr elem)
{
    int ret = 1;

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

    if (ctxt->elem == 0) {
        xmlRelaxNGPtr schema;
        xmlRelaxNGGrammarPtr grammar;
        xmlRegExecCtxtPtr exec;
        xmlRelaxNGDefinePtr define;

        schema = ctxt->schema;
        if (schema == NULL) {
            VALID_ERR(XML_RELAXNG_ERR_NOGRAMMAR);
            return (-1);
        }
        grammar = schema->topgrammar;
        if ((grammar == NULL) || (grammar->start == NULL)) {
            VALID_ERR(XML_RELAXNG_ERR_NOGRAMMAR);
            return (-1);
        }
        define = grammar->start;
        if (define->contModel == NULL) {
            ctxt->pdef = define;
            return (0);
        }
        exec = xmlRegNewExecCtxt(define->contModel,
                                 xmlRelaxNGValidateProgressiveCallback,
                                 ctxt);
        if (exec == NULL) {
            return (-1);
        }
        xmlRelaxNGElemPush(ctxt, exec);
    }
    ctxt->pnode = elem;
    ctxt->pstate = 0;
    if (elem->ns != NULL) {
        ret =
            xmlRegExecPushString2(ctxt->elem, elem->name, elem->ns->href,
                                  ctxt);
    } else {
        ret = xmlRegExecPushString(ctxt->elem, elem->name, ctxt);
    }
    if (ret < 0) {
        VALID_ERR2(XML_RELAXNG_ERR_ELEMWRONG, elem->name);
    } else {
        if (ctxt->pstate == 0)
            ret = 0;
        else if (ctxt->pstate < 0)
            ret = -1;
        else
            ret = 1;
    }
    return (ret);
}

/**
 * xmlRelaxNGValidatePushCData:
 * @ctxt:  the RelaxNG validation context
 * @data:  some character data read
 * @len:  the length of the data
 *
 * check the CData parsed for validation in the current stack
 *
 * returns 1 if no validation problem was found or -1 otherwise
 */
int
xmlRelaxNGValidatePushCData(xmlRelaxNGValidCtxtPtr ctxt,
                            const xmlChar * data, int len ATTRIBUTE_UNUSED)
{
    int ret = 1;

    if ((ctxt == NULL) || (ctxt->elem == NULL) || (data == NULL))
        return (-1);

    while (*data != 0) {
        if (!IS_BLANK_CH(*data))
            break;
        data++;
    }
    if (*data == 0)
        return (1);

    ret = xmlRegExecPushString(ctxt->elem, BAD_CAST "#text", ctxt);
    if (ret < 0) {
        VALID_ERR2(XML_RELAXNG_ERR_TEXTWRONG, BAD_CAST " TODO ");

        return (-1);
    }
    return (1);
}

/**
 * xmlRelaxNGValidatePopElement:
 * @ctxt:  the RelaxNG validation context
 * @doc:  a document instance
 * @elem:  an element instance
 *
 * Pop the element end from the RelaxNG validation stack.
 *
 * returns 1 if no validation problem was found or 0 otherwise
 */
int
xmlRelaxNGValidatePopElement(xmlRelaxNGValidCtxtPtr ctxt,
                             xmlDocPtr doc ATTRIBUTE_UNUSED,
                             xmlNodePtr elem)
{
    int ret;
    xmlRegExecCtxtPtr exec;

    if ((ctxt == NULL) || (ctxt->elem == NULL) || (elem == NULL))
        return (-1);
    /*
     * verify that we reached a terminal state of the content model.
     */
    exec = xmlRelaxNGElemPop(ctxt);
    ret = xmlRegExecPushString(exec, NULL, NULL);
    if (ret == 0) {
        /*
         * TODO: get some of the names needed to exit the current state of exec
         */
        VALID_ERR2(XML_RELAXNG_ERR_NOELEM, BAD_CAST "");
        ret = -1;
    } else if (ret < 0) {
        ret = -1;
    } else {
        ret = 1;
    }
    xmlRegFreeExecCtxt(exec);
    return (ret);
}

/**
 * xmlRelaxNGValidateFullElement:
 * @ctxt:  the validation context
 * @doc:  a document instance
 * @elem:  an element instance
 *
 * Validate a full subtree when xmlRelaxNGValidatePushElement() returned
 * 0 and the content of the node has been expanded.
 *
 * returns 1 if no validation problem was found or -1 in case of error.
 */
int
xmlRelaxNGValidateFullElement(xmlRelaxNGValidCtxtPtr ctxt,
                              xmlDocPtr doc ATTRIBUTE_UNUSED,
                              xmlNodePtr elem)
{
    int ret;
    xmlRelaxNGValidStatePtr state;

    if ((ctxt == NULL) || (ctxt->pdef == NULL) || (elem == NULL))
        return (-1);
    state = xmlRelaxNGNewValidState(ctxt, elem->parent);
    if (state == NULL) {
        return (-1);
    }
    state->seq = elem;
    ctxt->state = state;
    ctxt->errNo = XML_RELAXNG_OK;
    ret = xmlRelaxNGValidateDefinition(ctxt, ctxt->pdef);
    if ((ret != 0) || (ctxt->errNo != XML_RELAXNG_OK))
        ret = -1;
    else
        ret = 1;
    xmlRelaxNGFreeValidState(ctxt, ctxt->state);
    ctxt->state = NULL;
    return (ret);
}

/************************************************************************
 *									*
 *		Generic interpreted validation implementation		*
 *									*
 ************************************************************************/
static int xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
                                   xmlRelaxNGDefinePtr define);

/**
 * xmlRelaxNGSkipIgnored:
 * @ctxt:  a schema validation context
 * @node:  the top node.
 *
 * Skip ignorable nodes in that context
 *
 * Returns the new sibling or NULL in case of error.
 */
static xmlNodePtr
xmlRelaxNGSkipIgnored(xmlRelaxNGValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
                      xmlNodePtr node)
{
    /*
     * TODO complete and handle entities
     */
    while ((node != NULL) &&
           ((node->type == XML_COMMENT_NODE) ||
            (node->type == XML_PI_NODE) ||
	    (node->type == XML_XINCLUDE_START) ||
	    (node->type == XML_XINCLUDE_END) ||
            (((node->type == XML_TEXT_NODE) ||
              (node->type == XML_CDATA_SECTION_NODE)) &&
             ((ctxt->flags & FLAGS_MIXED_CONTENT) ||
              (IS_BLANK_NODE(node)))))) {
        node = node->next;
    }
    return (node);
}

/**
 * xmlRelaxNGNormalize:
 * @ctxt:  a schema validation context
 * @str:  the string to normalize
 *
 * Implements the  normalizeWhiteSpace( s ) function from
 * section 6.2.9 of the spec
 *
 * Returns the new string or NULL in case of error.
 */
static xmlChar *
xmlRelaxNGNormalize(xmlRelaxNGValidCtxtPtr ctxt, const xmlChar * str)
{
    xmlChar *ret, *p;
    const xmlChar *tmp;
    int len;

    if (str == NULL)
        return (NULL);
    tmp = str;
    while (*tmp != 0)
        tmp++;
    len = tmp - str;

    ret = (xmlChar *) xmlMallocAtomic(len + 1);
    if (ret == NULL) {
        xmlRngVErrMemory(ctxt);
        return (NULL);
    }
    p = ret;
    while (IS_BLANK_CH(*str))
        str++;
    while (*str != 0) {
        if (IS_BLANK_CH(*str)) {
            while (IS_BLANK_CH(*str))
                str++;
            if (*str == 0)
                break;
            *p++ = ' ';
        } else
            *p++ = *str++;
    }
    *p = 0;
    return (ret);
}

/**
 * xmlRelaxNGValidateDatatype:
 * @ctxt:  a Relax-NG validation context
 * @value:  the string value
 * @type:  the datatype definition
 * @node:  the node
 *
 * Validate the given value against the datatype
 *
 * Returns 0 if the validation succeeded or an error code.
 */
static int
xmlRelaxNGValidateDatatype(xmlRelaxNGValidCtxtPtr ctxt,
                           const xmlChar * value,
                           xmlRelaxNGDefinePtr define, xmlNodePtr node)
{
    int ret, tmp;
    xmlRelaxNGTypeLibraryPtr lib;
    void *result = NULL;
    xmlRelaxNGDefinePtr cur;

    if ((define == NULL) || (define->data == NULL)) {
        return (-1);
    }
    lib = (xmlRelaxNGTypeLibraryPtr) define->data;
    if (lib->check != NULL) {
        if ((define->attrs != NULL) &&
            (define->attrs->type == XML_RELAXNG_PARAM)) {
            ret =
                lib->check(lib->data, define->name, value, &result, node);
        } else {
            ret = lib->check(lib->data, define->name, value, NULL, node);
        }
    } else
        ret = -1;
    if (ret < 0) {
        VALID_ERR2(XML_RELAXNG_ERR_TYPE, define->name);
        if ((result != NULL) && (lib != NULL) && (lib->freef != NULL))
            lib->freef(lib->data, result);
        return (-1);
    } else if (ret == 1) {
        ret = 0;
    } else if (ret == 2) {
        VALID_ERR2P(XML_RELAXNG_ERR_DUPID, value);
    } else {
        VALID_ERR3P(XML_RELAXNG_ERR_TYPEVAL, define->name, value);
        ret = -1;
    }
    cur = define->attrs;
    while ((ret == 0) && (cur != NULL) && (cur->type == XML_RELAXNG_PARAM)) {
        if (lib->facet != NULL) {
            tmp = lib->facet(lib->data, define->name, cur->name,
                             cur->value, value, result);
            if (tmp != 0)
                ret = -1;
        }
        cur = cur->next;
    }
    if ((ret == 0) && (define->content != NULL)) {
        const xmlChar *oldvalue, *oldendvalue;

        oldvalue = ctxt->state->value;
        oldendvalue = ctxt->state->endvalue;
        ctxt->state->value = (xmlChar *) value;
        ctxt->state->endvalue = NULL;
        ret = xmlRelaxNGValidateValue(ctxt, define->content);
        ctxt->state->value = (xmlChar *) oldvalue;
        ctxt->state->endvalue = (xmlChar *) oldendvalue;
    }
    if ((result != NULL) && (lib != NULL) && (lib->freef != NULL))
        lib->freef(lib->data, result);
    return (ret);
}

/**
 * xmlRelaxNGNextValue:
 * @ctxt:  a Relax-NG validation context
 *
 * Skip to the next value when validating within a list
 *
 * Returns 0 if the operation succeeded or an error code.
 */
static int
xmlRelaxNGNextValue(xmlRelaxNGValidCtxtPtr ctxt)
{
    xmlChar *cur;

    cur = ctxt->state->value;
    if ((cur == NULL) || (ctxt->state->endvalue == NULL)) {
        ctxt->state->value = NULL;
        ctxt->state->endvalue = NULL;
        return (0);
    }
    while (*cur != 0)
        cur++;
    while ((cur != ctxt->state->endvalue) && (*cur == 0))
        cur++;
    if (cur == ctxt->state->endvalue)
        ctxt->state->value = NULL;
    else
        ctxt->state->value = cur;
    return (0);
}

/**
 * xmlRelaxNGValidateValueList:
 * @ctxt:  a Relax-NG validation context
 * @defines:  the list of definitions to verify
 *
 * Validate the given set of definitions for the current value
 *
 * Returns 0 if the validation succeeded or an error code.
 */
static int
xmlRelaxNGValidateValueList(xmlRelaxNGValidCtxtPtr ctxt,
                            xmlRelaxNGDefinePtr defines)
{
    int ret = 0;

    while (defines != NULL) {
        ret = xmlRelaxNGValidateValue(ctxt, defines);
        if (ret != 0)
            break;
        defines = defines->next;
    }
    return (ret);
}

/**
 * xmlRelaxNGValidateValue:
 * @ctxt:  a Relax-NG validation context
 * @define:  the definition to verify
 *
 * Validate the given definition for the current value
 *
 * Returns 0 if the validation succeeded or an error code.
 */
static int
xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
                        xmlRelaxNGDefinePtr define)
{
    int ret = 0, oldflags;
    xmlChar *value;

    value = ctxt->state->value;
    switch (define->type) {
        case XML_RELAXNG_EMPTY:{
                if ((value != NULL) && (value[0] != 0)) {
                    int idx = 0;

                    while (IS_BLANK_CH(value[idx]))
                        idx++;
                    if (value[idx] != 0)
                        ret = -1;
                }
                break;
            }
        case XML_RELAXNG_TEXT:
            break;
        case XML_RELAXNG_VALUE:{
                if (!xmlStrEqual(value, define->value)) {
                    if (define->name != NULL) {
                        xmlRelaxNGTypeLibraryPtr lib;

                        lib = (xmlRelaxNGTypeLibraryPtr) define->data;
                        if ((lib != NULL) && (lib->comp != NULL)) {
                            ret = lib->comp(lib->data, define->name,
                                            define->value, define->node,
                                            (void *) define->attrs,
                                            value, ctxt->state->node);
                        } else
                            ret = -1;
                        if (ret < 0) {
                            VALID_ERR2(XML_RELAXNG_ERR_TYPECMP,
                                       define->name);
                            return (-1);
                        } else if (ret == 1) {
                            ret = 0;
                        } else {
                            ret = -1;
                        }
                    } else {
                        xmlChar *nval, *nvalue;

                        /*
                         * TODO: trivial optimizations are possible by
                         * computing at compile-time
                         */
                        nval = xmlRelaxNGNormalize(ctxt, define->value);
                        nvalue = xmlRelaxNGNormalize(ctxt, value);

                        if ((nval == NULL) || (nvalue == NULL) ||
                            (!xmlStrEqual(nval, nvalue)))
                            ret = -1;
                        if (nval != NULL)
                            xmlFree(nval);
                        if (nvalue != NULL)
                            xmlFree(nvalue);
                    }
                }
                if (ret == 0)
                    xmlRelaxNGNextValue(ctxt);
                break;
            }
        case XML_RELAXNG_DATATYPE:{
                ret = xmlRelaxNGValidateDatatype(ctxt, value, define,
                                                 ctxt->state->seq);
                if (ret == 0)
                    xmlRelaxNGNextValue(ctxt);

                break;
            }
        case XML_RELAXNG_CHOICE:{
                xmlRelaxNGDefinePtr list = define->content;
                xmlChar *oldvalue;

                oldflags = ctxt->flags;
                ctxt->flags |= FLAGS_IGNORABLE;

                oldvalue = ctxt->state->value;
                while (list != NULL) {
                    ret = xmlRelaxNGValidateValue(ctxt, list);
                    if (ret == 0) {
                        break;
                    }
                    ctxt->state->value = oldvalue;
                    list = list->next;
                }
                ctxt->flags = oldflags;
                if (ret != 0) {
                    if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
                        xmlRelaxNGDumpValidError(ctxt);
                } else {
                    if (ctxt->errNr > 0)
                        xmlRelaxNGPopErrors(ctxt, 0);
                }
                break;
            }
        case XML_RELAXNG_LIST:{
                xmlRelaxNGDefinePtr list = define->content;
                xmlChar *oldvalue, *oldend, *val, *cur;

                oldvalue = ctxt->state->value;
                oldend = ctxt->state->endvalue;

                val = xmlStrdup(oldvalue);
                if (val == NULL) {
                    val = xmlStrdup(BAD_CAST "");
                }
                if (val == NULL) {
                    VALID_ERR(XML_RELAXNG_ERR_NOSTATE);
                    return (-1);
                }
                cur = val;
                while (*cur != 0) {
                    if (IS_BLANK_CH(*cur)) {
                        *cur = 0;
                        cur++;
                        while (IS_BLANK_CH(*cur))
                            *cur++ = 0;
                    } else
                        cur++;
                }
                ctxt->state->endvalue = cur;
                cur = val;
                while ((*cur == 0) && (cur != ctxt->state->endvalue))
                    cur++;

                ctxt->state->value = cur;

                while (list != NULL) {
                    if (ctxt->state->value == ctxt->state->endvalue)
                        ctxt->state->value = NULL;
                    ret = xmlRelaxNGValidateValue(ctxt, list);
                    if (ret != 0) {
                        break;
                    }
                    list = list->next;
                }

                if ((ret == 0) && (ctxt->state->value != NULL) &&
                    (ctxt->state->value != ctxt->state->endvalue)) {
                    VALID_ERR2(XML_RELAXNG_ERR_LISTEXTRA,
                               ctxt->state->value);
                    ret = -1;
                }
                xmlFree(val);
                ctxt->state->value = oldvalue;
                ctxt->state->endvalue = oldend;
                break;
            }
        case XML_RELAXNG_ONEORMORE:
            ret = xmlRelaxNGValidateValueList(ctxt, define->content);
            if (ret != 0) {
                break;
            }
            /* Falls through. */
        case XML_RELAXNG_ZEROORMORE:{
                xmlChar *cur, *temp;

                if ((ctxt->state->value == NULL) ||
                    (*ctxt->state->value == 0)) {
                    ret = 0;
                    break;
                }
                oldflags = ctxt->flags;
                ctxt->flags |= FLAGS_IGNORABLE;
                cur = ctxt->state->value;
                temp = NULL;
                while ((cur != NULL) && (cur != ctxt->state->endvalue) &&
                       (temp != cur)) {
                    temp = cur;
                    ret =
                        xmlRelaxNGValidateValueList(ctxt, define->content);
                    if (ret != 0) {
                        ctxt->state->value = temp;
                        ret = 0;
                        break;
                    }
                    cur = ctxt->state->value;
                }
                ctxt->flags = oldflags;
		if (ctxt->errNr > 0)
		    xmlRelaxNGPopErrors(ctxt, 0);
                break;
            }
        case XML_RELAXNG_OPTIONAL:{
                xmlChar *temp;

                if ((ctxt->state->value == NULL) ||
                    (*ctxt->state->value == 0)) {
                    ret = 0;
                    break;
                }
                oldflags = ctxt->flags;
                ctxt->flags |= FLAGS_IGNORABLE;
                temp = ctxt->state->value;
                ret = xmlRelaxNGValidateValue(ctxt, define->content);
                ctxt->flags = oldflags;
                if (ret != 0) {
                    ctxt->state->value = temp;
                    if (ctxt->errNr > 0)
                        xmlRelaxNGPopErrors(ctxt, 0);
                    ret = 0;
                    break;
                }
		if (ctxt->errNr > 0)
		    xmlRelaxNGPopErrors(ctxt, 0);
                break;
            }
        case XML_RELAXNG_EXCEPT:{
                xmlRelaxNGDefinePtr list;

                list = define->content;
                while (list != NULL) {
                    ret = xmlRelaxNGValidateValue(ctxt, list);
                    if (ret == 0) {
                        ret = -1;
                        break;
                    } else
                        ret = 0;
                    list = list->next;
                }
                break;
            }
        case XML_RELAXNG_DEF:
        case XML_RELAXNG_GROUP:{
                xmlRelaxNGDefinePtr list;

                list = define->content;
                while (list != NULL) {
                    ret = xmlRelaxNGValidateValue(ctxt, list);
                    if (ret != 0) {
                        ret = -1;
                        break;
                    } else
                        ret = 0;
                    list = list->next;
                }
                break;
            }
        case XML_RELAXNG_REF:
        case XML_RELAXNG_PARENTREF:
	    if (define->content == NULL) {
                VALID_ERR(XML_RELAXNG_ERR_NODEFINE);
                ret = -1;
	    } else {
                ret = xmlRelaxNGValidateValue(ctxt, define->content);
            }
            break;
        default:
            /* TODO */
            ret = -1;
    }
    return (ret);
}

/**
 * xmlRelaxNGValidateValueContent:
 * @ctxt:  a Relax-NG validation context
 * @defines:  the list of definitions to verify
 *
 * Validate the given definitions for the current value
 *
 * Returns 0 if the validation succeeded or an error code.
 */
static int
xmlRelaxNGValidateValueContent(xmlRelaxNGValidCtxtPtr ctxt,
                               xmlRelaxNGDefinePtr defines)
{
    int ret = 0;

    while (defines != NULL) {
        ret = xmlRelaxNGValidateValue(ctxt, defines);
        if (ret != 0)
            break;
        defines = defines->next;
    }
    return (ret);
}

/**
 * xmlRelaxNGAttributeMatch:
 * @ctxt:  a Relax-NG validation context
 * @define:  the definition to check
 * @prop:  the attribute
 *
 * Check if the attribute matches the definition nameClass
 *
 * Returns 1 if the attribute matches, 0 if no, or -1 in case of error
 */
static int
xmlRelaxNGAttributeMatch(xmlRelaxNGValidCtxtPtr ctxt,
                         xmlRelaxNGDefinePtr define, xmlAttrPtr prop)
{
    int ret;

    if (define->name != NULL) {
        if (!xmlStrEqual(define->name, prop->name))
            return (0);
    }
    if (define->ns != NULL) {
        if (define->ns[0] == 0) {
            if (prop->ns != NULL)
                return (0);
        } else {
            if ((prop->ns == NULL) ||
                (!xmlStrEqual(define->ns, prop->ns->href)))
                return (0);
        }
    }
    if (define->nameClass == NULL)
        return (1);
    define = define->nameClass;
    if (define->type == XML_RELAXNG_EXCEPT) {
        xmlRelaxNGDefinePtr list;

        list = define->content;
        while (list != NULL) {
            ret = xmlRelaxNGAttributeMatch(ctxt, list, prop);
            if (ret == 1)
                return (0);
            if (ret < 0)
                return (ret);
            list = list->next;
        }
    } else if (define->type == XML_RELAXNG_CHOICE) {
        xmlRelaxNGDefinePtr list;

        list = define->nameClass;
        while (list != NULL) {
            ret = xmlRelaxNGAttributeMatch(ctxt, list, prop);
            if (ret == 1)
                return (1);
            if (ret < 0)
                return (ret);
            list = list->next;
        }
        return (0);
    } else {
        /* TODO */
        return (0);
    }
    return (1);
}

/**
 * xmlRelaxNGValidateAttribute:
 * @ctxt:  a Relax-NG validation context
 * @define:  the definition to verify
 *
 * Validate the given attribute definition for that node
 *
 * Returns 0 if the validation succeeded or an error code.
 */
static int
xmlRelaxNGValidateAttribute(xmlRelaxNGValidCtxtPtr ctxt,
                            xmlRelaxNGDefinePtr define)
{
    int ret = 0, i;
    xmlChar *value, *oldvalue;
    xmlAttrPtr prop = NULL, tmp;
    xmlNodePtr oldseq;

    if (ctxt->state->nbAttrLeft <= 0)
        return (-1);
    if (define->name != NULL) {
        for (i = 0; i < ctxt->state->nbAttrs; i++) {
            tmp = ctxt->state->attrs[i];
            if ((tmp != NULL) && (xmlStrEqual(define->name, tmp->name))) {
                if ((((define->ns == NULL) || (define->ns[0] == 0)) &&
                     (tmp->ns == NULL)) ||
                    ((tmp->ns != NULL) &&
                     (xmlStrEqual(define->ns, tmp->ns->href)))) {
                    prop = tmp;
                    break;
                }
            }
        }
        if (prop != NULL) {
            value = xmlNodeListGetString(prop->doc, prop->children, 1);
            oldvalue = ctxt->state->value;
            oldseq = ctxt->state->seq;
            ctxt->state->seq = (xmlNodePtr) prop;
            ctxt->state->value = value;
            ctxt->state->endvalue = NULL;
            ret = xmlRelaxNGValidateValueContent(ctxt, define->content);
            if (ctxt->state->value != NULL)
                value = ctxt->state->value;
            if (value != NULL)
                xmlFree(value);
            ctxt->state->value = oldvalue;
            ctxt->state->seq = oldseq;
            if (ret == 0) {
                /*
                 * flag the attribute as processed
                 */
                ctxt->state->attrs[i] = NULL;
                ctxt->state->nbAttrLeft--;
            }
        } else {
            ret = -1;
        }
    } else {
        for (i = 0; i < ctxt->state->nbAttrs; i++) {
            tmp = ctxt->state->attrs[i];
            if ((tmp != NULL) &&
                (xmlRelaxNGAttributeMatch(ctxt, define, tmp) == 1)) {
                prop = tmp;
                break;
            }
        }
        if (prop != NULL) {
            value = xmlNodeListGetString(prop->doc, prop->children, 1);
            oldvalue = ctxt->state->value;
            oldseq = ctxt->state->seq;
            ctxt->state->seq = (xmlNodePtr) prop;
            ctxt->state->value = value;
            ret = xmlRelaxNGValidateValueContent(ctxt, define->content);
            if (ctxt->state->value != NULL)
                value = ctxt->state->value;
            if (value != NULL)
                xmlFree(value);
            ctxt->state->value = oldvalue;
            ctxt->state->seq = oldseq;
            if (ret == 0) {
                /*
                 * flag the attribute as processed
                 */
                ctxt->state->attrs[i] = NULL;
                ctxt->state->nbAttrLeft--;
            }
        } else {
            ret = -1;
        }
    }

    return (ret);
}

/**
 * xmlRelaxNGValidateAttributeList:
 * @ctxt:  a Relax-NG validation context
 * @define:  the list of definition to verify
 *
 * Validate the given node against the list of attribute definitions
 *
 * Returns 0 if the validation succeeded or an error code.
 */
static int
xmlRelaxNGValidateAttributeList(xmlRelaxNGValidCtxtPtr ctxt,
                                xmlRelaxNGDefinePtr defines)
{
    int ret = 0, res;
    int needmore = 0;
    xmlRelaxNGDefinePtr cur;

    cur = defines;
    while (cur != NULL) {
        if (cur->type == XML_RELAXNG_ATTRIBUTE) {
            if (xmlRelaxNGValidateAttribute(ctxt, cur) != 0)
                ret = -1;
        } else
            needmore = 1;
        cur = cur->next;
    }
    if (!needmore)
        return (ret);
    cur = defines;
    while (cur != NULL) {
        if (cur->type != XML_RELAXNG_ATTRIBUTE) {
            if ((ctxt->state != NULL) || (ctxt->states != NULL)) {
                res = xmlRelaxNGValidateDefinition(ctxt, cur);
                if (res < 0)
                    ret = -1;
            } else {
                VALID_ERR(XML_RELAXNG_ERR_NOSTATE);
                return (-1);
            }
            if (res == -1)      /* continues on -2 */
                break;
        }
        cur = cur->next;
    }

    return (ret);
}

/**
 * xmlRelaxNGNodeMatchesList:
 * @node:  the node
 * @list:  a NULL terminated array of definitions
 *
 * Check if a node can be matched by one of the definitions
 *
 * Returns 1 if matches 0 otherwise
 */
static int
xmlRelaxNGNodeMatchesList(xmlNodePtr node, xmlRelaxNGDefinePtr * list)
{
    xmlRelaxNGDefinePtr cur;
    int i = 0, tmp;

    if ((node == NULL) || (list == NULL))
        return (0);

    cur = list[i++];
    while (cur != NULL) {
        if ((node->type == XML_ELEMENT_NODE) &&
            (cur->type == XML_RELAXNG_ELEMENT)) {
            tmp = xmlRelaxNGElementMatch(NULL, cur, node);
            if (tmp == 1)
                return (1);
        } else if (((node->type == XML_TEXT_NODE) ||
                    (node->type == XML_CDATA_SECTION_NODE)) &&
                   ((cur->type == XML_RELAXNG_DATATYPE) ||
		    (cur->type == XML_RELAXNG_LIST) ||
                    (cur->type == XML_RELAXNG_TEXT) ||
                    (cur->type == XML_RELAXNG_VALUE))) {
            return (1);
        }
        cur = list[i++];
    }
    return (0);
}

/**
 * xmlRelaxNGValidateInterleave:
 * @ctxt:  a Relax-NG validation context
 * @define:  the definition to verify
 *
 * Validate an interleave definition for a node.
 *
 * Returns 0 if the validation succeeded or an error code.
 */
static int
xmlRelaxNGValidateInterleave(xmlRelaxNGValidCtxtPtr ctxt,
                             xmlRelaxNGDefinePtr define)
{
    int ret = 0, i, nbgroups;
    int errNr = ctxt->errNr;
    int oldflags;

    xmlRelaxNGValidStatePtr oldstate;
    xmlRelaxNGPartitionPtr partitions;
    xmlRelaxNGInterleaveGroupPtr group = NULL;
    xmlNodePtr cur, start, last = NULL, lastchg = NULL, lastelem;
    xmlNodePtr *list = NULL, *lasts = NULL;

    if (define->data != NULL) {
        partitions = (xmlRelaxNGPartitionPtr) define->data;
        nbgroups = partitions->nbgroups;
    } else {
        VALID_ERR(XML_RELAXNG_ERR_INTERNODATA);
        return (-1);
    }
    /*
     * Optimizations for MIXED
     */
    oldflags = ctxt->flags;
    if (define->dflags & IS_MIXED) {
        ctxt->flags |= FLAGS_MIXED_CONTENT;
        if (nbgroups == 2) {
            /*
             * this is a pure <mixed> case
             */
            if (ctxt->state != NULL)
                ctxt->state->seq = xmlRelaxNGSkipIgnored(ctxt,
                                                         ctxt->state->seq);
            if (partitions->groups[0]->rule->type == XML_RELAXNG_TEXT)
                ret = xmlRelaxNGValidateDefinition(ctxt,
                                                   partitions->groups[1]->
                                                   rule);
            else
                ret = xmlRelaxNGValidateDefinition(ctxt,
                                                   partitions->groups[0]->
                                                   rule);
            if (ret == 0) {
                if (ctxt->state != NULL)
                    ctxt->state->seq = xmlRelaxNGSkipIgnored(ctxt,
                                                             ctxt->state->
                                                             seq);
            }
            ctxt->flags = oldflags;
            return (ret);
        }
    }

    /*
     * Build arrays to store the first and last node of the chain
     * pertaining to each group
     */
    list = (xmlNodePtr *) xmlMalloc(nbgroups * sizeof(xmlNodePtr));
    if (list == NULL) {
        xmlRngVErrMemory(ctxt);
        return (-1);
    }
    memset(list, 0, nbgroups * sizeof(xmlNodePtr));
    lasts = (xmlNodePtr *) xmlMalloc(nbgroups * sizeof(xmlNodePtr));
    if (lasts == NULL) {
        xmlRngVErrMemory(ctxt);
        return (-1);
    }
    memset(lasts, 0, nbgroups * sizeof(xmlNodePtr));

    /*
     * Walk the sequence of children finding the right group and
     * sorting them in sequences.
     */
    cur = ctxt->state->seq;
    cur = xmlRelaxNGSkipIgnored(ctxt, cur);
    start = cur;
    while (cur != NULL) {
        ctxt->state->seq = cur;
        if ((partitions->triage != NULL) &&
            (partitions->flags & IS_DETERMINIST)) {
            void *tmp = NULL;

            if ((cur->type == XML_TEXT_NODE) ||
                (cur->type == XML_CDATA_SECTION_NODE)) {
                tmp = xmlHashLookup2(partitions->triage, BAD_CAST "#text",
                                     NULL);
            } else if (cur->type == XML_ELEMENT_NODE) {
                if (cur->ns != NULL) {
                    tmp = xmlHashLookup2(partitions->triage, cur->name,
                                         cur->ns->href);
                    if (tmp == NULL)
                        tmp = xmlHashLookup2(partitions->triage,
                                             BAD_CAST "#any",
                                             cur->ns->href);
                } else
                    tmp =
                        xmlHashLookup2(partitions->triage, cur->name,
                                       NULL);
                if (tmp == NULL)
                    tmp =
                        xmlHashLookup2(partitions->triage, BAD_CAST "#any",
                                       NULL);
            }

            if (tmp == NULL) {
                i = nbgroups;
            } else {
                i = ((ptrdiff_t) tmp) - 1;
                if (partitions->flags & IS_NEEDCHECK) {
                    group = partitions->groups[i];
                    if (!xmlRelaxNGNodeMatchesList(cur, group->defs))
                        i = nbgroups;
                }
            }
        } else {
            for (i = 0; i < nbgroups; i++) {
                group = partitions->groups[i];
                if (group == NULL)
                    continue;
                if (xmlRelaxNGNodeMatchesList(cur, group->defs))
                    break;
            }
        }
        /*
         * We break as soon as an element not matched is found
         */
        if (i >= nbgroups) {
            break;
        }
        if (lasts[i] != NULL) {
            lasts[i]->next = cur;
            lasts[i] = cur;
        } else {
            list[i] = cur;
            lasts[i] = cur;
        }
        if (cur->next != NULL)
            lastchg = cur->next;
        else
            lastchg = cur;
        cur = xmlRelaxNGSkipIgnored(ctxt, cur->next);
    }
    if (ret != 0) {
        VALID_ERR(XML_RELAXNG_ERR_INTERSEQ);
        ret = -1;
        goto done;
    }
    lastelem = cur;
    oldstate = ctxt->state;
    for (i = 0; i < nbgroups; i++) {
        ctxt->state = xmlRelaxNGCopyValidState(ctxt, oldstate);
	if (ctxt->state == NULL) {
	    ret = -1;
	    break;
	}
        group = partitions->groups[i];
        if (lasts[i] != NULL) {
            last = lasts[i]->next;
            lasts[i]->next = NULL;
        }
        ctxt->state->seq = list[i];
        ret = xmlRelaxNGValidateDefinition(ctxt, group->rule);
        if (ret != 0)
            break;
        if (ctxt->state != NULL) {
            cur = ctxt->state->seq;
            cur = xmlRelaxNGSkipIgnored(ctxt, cur);
            xmlRelaxNGFreeValidState(ctxt, oldstate);
            oldstate = ctxt->state;
            ctxt->state = NULL;
            if (cur != NULL
                    /* there's a nasty violation of context-free unambiguities,
                       since in open-name-class context, interleave in the
                       production shall finish without caring about anything
                       else that is OK to follow in that case -- it would
                       otherwise get marked as "extra content" and would
                       hence fail the validation, hence this perhaps
                       dirty attempt to rectify such a situation */
                    && (define->parent->type != XML_RELAXNG_DEF
                        || !xmlStrEqual(define->parent->name,
                                        (const xmlChar *) "open-name-class"))) {
                VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA, cur->name);
                ret = -1;
                ctxt->state = oldstate;
                goto done;
            }
        } else if (ctxt->states != NULL) {
            int j;
            int found = 0;
	    int best = -1;
	    int lowattr = -1;

	    /*
	     * PBM: what happen if there is attributes checks in the interleaves
	     */

            for (j = 0; j < ctxt->states->nbState; j++) {
                cur = ctxt->states->tabState[j]->seq;
                cur = xmlRelaxNGSkipIgnored(ctxt, cur);
                if (cur == NULL) {
		    if (found == 0) {
		        lowattr = ctxt->states->tabState[j]->nbAttrLeft;
			best = j;
		    }
                    found = 1;
		    if (ctxt->states->tabState[j]->nbAttrLeft <= lowattr) {
		        /* try  to keep the latest one to mach old heuristic */
		        lowattr = ctxt->states->tabState[j]->nbAttrLeft;
			best = j;
		    }
                    if (lowattr == 0)
		        break;
                } else if (found == 0) {
                    if (lowattr == -1) {
		        lowattr = ctxt->states->tabState[j]->nbAttrLeft;
			best = j;
		    } else
		    if (ctxt->states->tabState[j]->nbAttrLeft <= lowattr)  {
		        /* try  to keep the latest one to mach old heuristic */
		        lowattr = ctxt->states->tabState[j]->nbAttrLeft;
			best = j;
		    }
		}
            }
	    /*
	     * BIG PBM: here we pick only one restarting point :-(
	     */
            if (ctxt->states->nbState > 0) {
                xmlRelaxNGFreeValidState(ctxt, oldstate);
		if (best != -1) {
		    oldstate = ctxt->states->tabState[best];
		    ctxt->states->tabState[best] = NULL;
		} else {
		    oldstate =
			ctxt->states->tabState[ctxt->states->nbState - 1];
                    ctxt->states->tabState[ctxt->states->nbState - 1] = NULL;
                    ctxt->states->nbState--;
		}
            }
            for (j = 0; j < ctxt->states->nbState ; j++) {
                xmlRelaxNGFreeValidState(ctxt, ctxt->states->tabState[j]);
            }
            xmlRelaxNGFreeStates(ctxt, ctxt->states);
            ctxt->states = NULL;
            if (found == 0) {
                if (cur == NULL) {
		    VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA,
			       (const xmlChar *) "noname");
                } else {
                    VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA, cur->name);
                }
                ret = -1;
                ctxt->state = oldstate;
                goto done;
            }
        } else {
            ret = -1;
            break;
        }
        if (lasts[i] != NULL) {
            lasts[i]->next = last;
        }
    }
    if (ctxt->state != NULL)
        xmlRelaxNGFreeValidState(ctxt, ctxt->state);
    ctxt->state = oldstate;
    ctxt->state->seq = lastelem;
    if (ret != 0) {
        VALID_ERR(XML_RELAXNG_ERR_INTERSEQ);
        ret = -1;
        goto done;
    }

  done:
    ctxt->flags = oldflags;
    /*
     * builds the next links chain from the prev one
     */
    cur = lastchg;
    while (cur != NULL) {
        if ((cur == start) || (cur->prev == NULL))
            break;
        cur->prev->next = cur;
        cur = cur->prev;
    }
    if (ret == 0) {
        if (ctxt->errNr > errNr)
            xmlRelaxNGPopErrors(ctxt, errNr);
    }

    xmlFree(list);
    xmlFree(lasts);
    return (ret);
}

/**
 * xmlRelaxNGValidateDefinitionList:
 * @ctxt:  a Relax-NG validation context
 * @define:  the list of definition to verify
 *
 * Validate the given node content against the (list) of definitions
 *
 * Returns 0 if the validation succeeded or an error code.
 */
static int
xmlRelaxNGValidateDefinitionList(xmlRelaxNGValidCtxtPtr ctxt,
                                 xmlRelaxNGDefinePtr defines)
{
    int ret = 0, res;


    if (defines == NULL) {
        VALID_ERR2(XML_RELAXNG_ERR_INTERNAL,
                   BAD_CAST "NULL definition list");
        return (-1);
    }
    while (defines != NULL) {
        if ((ctxt->state != NULL) || (ctxt->states != NULL)) {
            res = xmlRelaxNGValidateDefinition(ctxt, defines);
            if (res < 0)
                ret = -1;
        } else {
            VALID_ERR(XML_RELAXNG_ERR_NOSTATE);
            return (-1);
        }
        if (res == -1)          /* continues on -2 */
            break;
        defines = defines->next;
    }

    return (ret);
}

/**
 * xmlRelaxNGElementMatch:
 * @ctxt:  a Relax-NG validation context
 * @define:  the definition to check
 * @elem:  the element
 *
 * Check if the element matches the definition nameClass
 *
 * Returns 1 if the element matches, 0 if no, or -1 in case of error
 */
static int
xmlRelaxNGElementMatch(xmlRelaxNGValidCtxtPtr ctxt,
                       xmlRelaxNGDefinePtr define, xmlNodePtr elem)
{
    int ret = 0, oldflags = 0;

    if (define->name != NULL) {
        if (!xmlStrEqual(elem->name, define->name)) {
            VALID_ERR3(XML_RELAXNG_ERR_ELEMNAME, define->name, elem->name);
            return (0);
        }
    }
    if ((define->ns != NULL) && (define->ns[0] != 0)) {
        if (elem->ns == NULL) {
            VALID_ERR2(XML_RELAXNG_ERR_ELEMNONS, elem->name);
            return (0);
        } else if (!xmlStrEqual(elem->ns->href, define->ns)) {
            VALID_ERR3(XML_RELAXNG_ERR_ELEMWRONGNS,
                       elem->name, define->ns);
            return (0);
        }
    } else if ((elem->ns != NULL) && (define->ns != NULL) &&
               (define->name == NULL)) {
        VALID_ERR2(XML_RELAXNG_ERR_ELEMEXTRANS, elem->name);
        return (0);
    } else if ((elem->ns != NULL) && (define->name != NULL)) {
        VALID_ERR2(XML_RELAXNG_ERR_ELEMEXTRANS, define->name);
        return (0);
    }

    if (define->nameClass == NULL)
        return (1);

    define = define->nameClass;
    if (define->type == XML_RELAXNG_EXCEPT) {
        xmlRelaxNGDefinePtr list;

        if (ctxt != NULL) {
            oldflags = ctxt->flags;
            ctxt->flags |= FLAGS_IGNORABLE;
        }

        list = define->content;
        while (list != NULL) {
            ret = xmlRelaxNGElementMatch(ctxt, list, elem);
            if (ret == 1) {
                if (ctxt != NULL)
                    ctxt->flags = oldflags;
                return (0);
            }
            if (ret < 0) {
                if (ctxt != NULL)
                    ctxt->flags = oldflags;
                return (ret);
            }
            list = list->next;
        }
        ret = 1;
        if (ctxt != NULL) {
            ctxt->flags = oldflags;
        }
    } else if (define->type == XML_RELAXNG_CHOICE) {
        xmlRelaxNGDefinePtr list;

        if (ctxt != NULL) {
            oldflags = ctxt->flags;
            ctxt->flags |= FLAGS_IGNORABLE;
        }

        list = define->nameClass;
        while (list != NULL) {
            ret = xmlRelaxNGElementMatch(ctxt, list, elem);
            if (ret == 1) {
                if (ctxt != NULL)
                    ctxt->flags = oldflags;
                return (1);
            }
            if (ret < 0) {
                if (ctxt != NULL)
                    ctxt->flags = oldflags;
                return (ret);
            }
            list = list->next;
        }
        if (ctxt != NULL) {
            if (ret != 0) {
                if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
                    xmlRelaxNGDumpValidError(ctxt);
            } else {
                if (ctxt->errNr > 0)
                    xmlRelaxNGPopErrors(ctxt, 0);
            }
        }
        ret = 0;
        if (ctxt != NULL) {
            ctxt->flags = oldflags;
        }
    } else {
        /* TODO */
        ret = -1;
    }
    return (ret);
}

/**
 * xmlRelaxNGBestState:
 * @ctxt:  a Relax-NG validation context
 *
 * Find the "best" state in the ctxt->states list of states to report
 * errors about. I.e. a state with no element left in the child list
 * or the one with the less attributes left.
 * This is called only if a validation error was detected
 *
 * Returns the index of the "best" state or -1 in case of error
 */
static int
xmlRelaxNGBestState(xmlRelaxNGValidCtxtPtr ctxt)
{
    xmlRelaxNGValidStatePtr state;
    int i, tmp;
    int best = -1;
    int value = 1000000;

    if ((ctxt == NULL) || (ctxt->states == NULL) ||
        (ctxt->states->nbState <= 0))
        return (-1);

    for (i = 0; i < ctxt->states->nbState; i++) {
        state = ctxt->states->tabState[i];
        if (state == NULL)
            continue;
        if (state->seq != NULL) {
            if ((best == -1) || (value > 100000)) {
                value = 100000;
                best = i;
            }
        } else {
            tmp = state->nbAttrLeft;
            if ((best == -1) || (value > tmp)) {
                value = tmp;
                best = i;
            }
        }
    }
    return (best);
}

/**
 * xmlRelaxNGLogBestError:
 * @ctxt:  a Relax-NG validation context
 *
 * Find the "best" state in the ctxt->states list of states to report
 * errors about and log it.
 */
static void
xmlRelaxNGLogBestError(xmlRelaxNGValidCtxtPtr ctxt)
{
    int best;

    if ((ctxt == NULL) || (ctxt->states == NULL) ||
        (ctxt->states->nbState <= 0))
        return;

    best = xmlRelaxNGBestState(ctxt);
    if ((best >= 0) && (best < ctxt->states->nbState)) {
        ctxt->state = ctxt->states->tabState[best];

        xmlRelaxNGValidateElementEnd(ctxt, 1);
    }
}

/**
 * xmlRelaxNGValidateElementEnd:
 * @ctxt:  a Relax-NG validation context
 * @dolog:  indicate that error logging should be done
 *
 * Validate the end of the element, implements check that
 * there is nothing left not consumed in the element content
 * or in the attribute list.
 *
 * Returns 0 if the validation succeeded or an error code.
 */
static int
xmlRelaxNGValidateElementEnd(xmlRelaxNGValidCtxtPtr ctxt, int dolog)
{
    int i;
    xmlRelaxNGValidStatePtr state;

    state = ctxt->state;
    if (state->seq != NULL) {
        state->seq = xmlRelaxNGSkipIgnored(ctxt, state->seq);
        if (state->seq != NULL) {
            if (dolog) {
                VALID_ERR3(XML_RELAXNG_ERR_EXTRACONTENT,
                           state->node->name, state->seq->name);
            }
            return (-1);
        }
    }
    for (i = 0; i < state->nbAttrs; i++) {
        if (state->attrs[i] != NULL) {
            if (dolog) {
                VALID_ERR3(XML_RELAXNG_ERR_INVALIDATTR,
                           state->attrs[i]->name, state->node->name);
            }
            return (-1 - i);
        }
    }
    return (0);
}

/**
 * xmlRelaxNGValidateState:
 * @ctxt:  a Relax-NG validation context
 * @define:  the definition to verify
 *
 * Validate the current state against the definition
 *
 * Returns 0 if the validation succeeded or an error code.
 */
static int
xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
                        xmlRelaxNGDefinePtr define)
{
    xmlNodePtr node;
    int ret = 0, i, tmp, oldflags, errNr;
    xmlRelaxNGValidStatePtr oldstate = NULL, state;

    if (define == NULL) {
        VALID_ERR(XML_RELAXNG_ERR_NODEFINE);
        return (-1);
    }

    if (ctxt->state != NULL) {
        node = ctxt->state->seq;
    } else {
        node = NULL;
    }
    ctxt->depth++;
    switch (define->type) {
        case XML_RELAXNG_EMPTY:
            ret = 0;
            break;
        case XML_RELAXNG_NOT_ALLOWED:
            ret = -1;
            break;
        case XML_RELAXNG_TEXT:
            while ((node != NULL) &&
                   ((node->type == XML_TEXT_NODE) ||
                    (node->type == XML_COMMENT_NODE) ||
                    (node->type == XML_PI_NODE) ||
                    (node->type == XML_CDATA_SECTION_NODE)))
                node = node->next;
            ctxt->state->seq = node;
            break;
        case XML_RELAXNG_ELEMENT:
            errNr = ctxt->errNr;
            node = xmlRelaxNGSkipIgnored(ctxt, node);
            if (node == NULL) {
                VALID_ERR2(XML_RELAXNG_ERR_NOELEM, define->name);
                ret = -1;
                if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
                    xmlRelaxNGDumpValidError(ctxt);
                break;
            }
            if (node->type != XML_ELEMENT_NODE) {
                VALID_ERR(XML_RELAXNG_ERR_NOTELEM);
                ret = -1;
                if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
                    xmlRelaxNGDumpValidError(ctxt);
                break;
            }
            /*
             * This node was already validated successfully against
             * this definition.
             */
            if (node->psvi == define) {
                ctxt->state->seq = xmlRelaxNGSkipIgnored(ctxt, node->next);
                if (ctxt->errNr > errNr)
                    xmlRelaxNGPopErrors(ctxt, errNr);
                if (ctxt->errNr != 0) {
                    while ((ctxt->err != NULL) &&
                           (((ctxt->err->err == XML_RELAXNG_ERR_ELEMNAME)
                             && (xmlStrEqual(ctxt->err->arg2, node->name)))
                            ||
                            ((ctxt->err->err ==
                              XML_RELAXNG_ERR_ELEMEXTRANS)
                             && (xmlStrEqual(ctxt->err->arg1, node->name)))
                            || (ctxt->err->err == XML_RELAXNG_ERR_NOELEM)
                            || (ctxt->err->err ==
                                XML_RELAXNG_ERR_NOTELEM)))
                        xmlRelaxNGValidErrorPop(ctxt);
                }
                break;
            }

            ret = xmlRelaxNGElementMatch(ctxt, define, node);
            if (ret <= 0) {
                ret = -1;
                if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
                    xmlRelaxNGDumpValidError(ctxt);
                break;
            }
            ret = 0;
            if (ctxt->errNr != 0) {
                if (ctxt->errNr > errNr)
                    xmlRelaxNGPopErrors(ctxt, errNr);
                while ((ctxt->err != NULL) &&
                       (((ctxt->err->err == XML_RELAXNG_ERR_ELEMNAME) &&
                         (xmlStrEqual(ctxt->err->arg2, node->name))) ||
                        ((ctxt->err->err == XML_RELAXNG_ERR_ELEMEXTRANS) &&
                         (xmlStrEqual(ctxt->err->arg1, node->name))) ||
                        (ctxt->err->err == XML_RELAXNG_ERR_NOELEM) ||
                        (ctxt->err->err == XML_RELAXNG_ERR_NOTELEM)))
                    xmlRelaxNGValidErrorPop(ctxt);
            }
            errNr = ctxt->errNr;

            oldflags = ctxt->flags;
            if (ctxt->flags & FLAGS_MIXED_CONTENT) {
                ctxt->flags -= FLAGS_MIXED_CONTENT;
            }
            state = xmlRelaxNGNewValidState(ctxt, node);
            if (state == NULL) {
                ret = -1;
                if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
                    xmlRelaxNGDumpValidError(ctxt);
                break;
            }

            oldstate = ctxt->state;
            ctxt->state = state;
            if (define->attrs != NULL) {
                tmp = xmlRelaxNGValidateAttributeList(ctxt, define->attrs);
                if (tmp != 0) {
                    ret = -1;
                    VALID_ERR2(XML_RELAXNG_ERR_ATTRVALID, node->name);
                }
            }
            if (define->contModel != NULL) {
                xmlRelaxNGValidStatePtr nstate, tmpstate = ctxt->state;
                xmlRelaxNGStatesPtr tmpstates = ctxt->states;
                xmlNodePtr nseq;

                nstate = xmlRelaxNGNewValidState(ctxt, node);
                ctxt->state = nstate;
                ctxt->states = NULL;

                tmp = xmlRelaxNGValidateCompiledContent(ctxt,
                                                        define->contModel,
                                                        ctxt->state->seq);
                nseq = ctxt->state->seq;
                ctxt->state = tmpstate;
                ctxt->states = tmpstates;
                xmlRelaxNGFreeValidState(ctxt, nstate);

                if (tmp != 0)
                    ret = -1;

                if (ctxt->states != NULL) {
                    tmp = -1;

                    for (i = 0; i < ctxt->states->nbState; i++) {
                        state = ctxt->states->tabState[i];
                        ctxt->state = state;
                        ctxt->state->seq = nseq;

                        if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
                            tmp = 0;
                            break;
                        }
                    }
                    if (tmp != 0) {
                        /*
                         * validation error, log the message for the "best" one
                         */
                        ctxt->flags |= FLAGS_IGNORABLE;
                        xmlRelaxNGLogBestError(ctxt);
                    }
                    for (i = 0; i < ctxt->states->nbState; i++) {
                        xmlRelaxNGFreeValidState(ctxt,
                                                 ctxt->states->
                                                 tabState[i]);
                    }
                    xmlRelaxNGFreeStates(ctxt, ctxt->states);
                    ctxt->flags = oldflags;
                    ctxt->states = NULL;
                    if ((ret == 0) && (tmp == -1))
                        ret = -1;
                } else {
                    state = ctxt->state;
		    if (ctxt->state != NULL)
			ctxt->state->seq = nseq;
                    if (ret == 0)
                        ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
                    xmlRelaxNGFreeValidState(ctxt, state);
                }
            } else {
                if (define->content != NULL) {
                    tmp = xmlRelaxNGValidateDefinitionList(ctxt,
                                                           define->
                                                           content);
                    if (tmp != 0) {
                        ret = -1;
                        if (ctxt->state == NULL) {
                            ctxt->state = oldstate;
                            VALID_ERR2(XML_RELAXNG_ERR_CONTENTVALID,
                                       node->name);
                            ctxt->state = NULL;
                        } else {
                            VALID_ERR2(XML_RELAXNG_ERR_CONTENTVALID,
                                       node->name);
                        }

                    }
                }
                if (ctxt->states != NULL) {
                    tmp = -1;

                    for (i = 0; i < ctxt->states->nbState; i++) {
                        state = ctxt->states->tabState[i];
                        ctxt->state = state;

                        if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
                            tmp = 0;
                            break;
                        }
                    }
                    if (tmp != 0) {
                        /*
                         * validation error, log the message for the "best" one
                         */
                        ctxt->flags |= FLAGS_IGNORABLE;
                        xmlRelaxNGLogBestError(ctxt);
                    }
                    for (i = 0; i < ctxt->states->nbState; i++) {
                        xmlRelaxNGFreeValidState(ctxt,
                                                 ctxt->states->tabState[i]);
                        ctxt->states->tabState[i] = NULL;
                    }
                    xmlRelaxNGFreeStates(ctxt, ctxt->states);
                    ctxt->flags = oldflags;
                    ctxt->states = NULL;
                    if ((ret == 0) && (tmp == -1))
                        ret = -1;
                } else {
                    state = ctxt->state;
                    if (ret == 0)
                        ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
                    xmlRelaxNGFreeValidState(ctxt, state);
                }
            }
            if (ret == 0) {
                node->psvi = define;
            }
            ctxt->flags = oldflags;
            ctxt->state = oldstate;
            if (oldstate != NULL)
                oldstate->seq = xmlRelaxNGSkipIgnored(ctxt, node->next);
            if (ret != 0) {
                if ((ctxt->flags & FLAGS_IGNORABLE) == 0) {
                    xmlRelaxNGDumpValidError(ctxt);
                    ret = 0;
#if 0
                } else {
                    ret = -2;
#endif
                }
            } else {
                if (ctxt->errNr > errNr)
                    xmlRelaxNGPopErrors(ctxt, errNr);
            }

            break;
        case XML_RELAXNG_OPTIONAL:{
                errNr = ctxt->errNr;
                oldflags = ctxt->flags;
                ctxt->flags |= FLAGS_IGNORABLE;
                oldstate = xmlRelaxNGCopyValidState(ctxt, ctxt->state);
                ret =
                    xmlRelaxNGValidateDefinitionList(ctxt,
                                                     define->content);
                if (ret != 0) {
                    if (ctxt->state != NULL)
                        xmlRelaxNGFreeValidState(ctxt, ctxt->state);
                    ctxt->state = oldstate;
                    ctxt->flags = oldflags;
                    ret = 0;
                    if (ctxt->errNr > errNr)
                        xmlRelaxNGPopErrors(ctxt, errNr);
                    break;
                }
                if (ctxt->states != NULL) {
                    xmlRelaxNGAddStates(ctxt, ctxt->states, oldstate);
                } else {
                    ctxt->states = xmlRelaxNGNewStates(ctxt, 1);
                    if (ctxt->states == NULL) {
                        xmlRelaxNGFreeValidState(ctxt, oldstate);
                        ctxt->flags = oldflags;
                        ret = -1;
                        if (ctxt->errNr > errNr)
                            xmlRelaxNGPopErrors(ctxt, errNr);
                        break;
                    }
                    xmlRelaxNGAddStates(ctxt, ctxt->states, oldstate);
                    xmlRelaxNGAddStates(ctxt, ctxt->states, ctxt->state);
                    ctxt->state = NULL;
                }
                ctxt->flags = oldflags;
                ret = 0;
                if (ctxt->errNr > errNr)
                    xmlRelaxNGPopErrors(ctxt, errNr);
                break;
            }
        case XML_RELAXNG_ONEORMORE:
            errNr = ctxt->errNr;
            ret = xmlRelaxNGValidateDefinitionList(ctxt, define->content);
            if (ret != 0) {
                break;
            }
            if (ctxt->errNr > errNr)
                xmlRelaxNGPopErrors(ctxt, errNr);
            /* Falls through. */
        case XML_RELAXNG_ZEROORMORE:{
                int progress;
                xmlRelaxNGStatesPtr states = NULL, res = NULL;
                int base, j;

                errNr = ctxt->errNr;
                res = xmlRelaxNGNewStates(ctxt, 1);
                if (res == NULL) {
                    ret = -1;
                    break;
                }
                /*
                 * All the input states are also exit states
                 */
                if (ctxt->state != NULL) {
                    xmlRelaxNGAddStates(ctxt, res,
                                        xmlRelaxNGCopyValidState(ctxt,
                                                                 ctxt->
                                                                 state));
                } else {
                    for (j = 0; j < ctxt->states->nbState; j++) {
                        xmlRelaxNGAddStates(ctxt, res,
                            xmlRelaxNGCopyValidState(ctxt,
                                            ctxt->states->tabState[j]));
                    }
                }
                oldflags = ctxt->flags;
                ctxt->flags |= FLAGS_IGNORABLE;
                do {
                    progress = 0;
                    base = res->nbState;

                    if (ctxt->states != NULL) {
                        states = ctxt->states;
                        for (i = 0; i < states->nbState; i++) {
                            ctxt->state = states->tabState[i];
                            ctxt->states = NULL;
                            ret = xmlRelaxNGValidateDefinitionList(ctxt,
                                                                   define->
                                                                   content);
                            if (ret == 0) {
                                if (ctxt->state != NULL) {
                                    tmp = xmlRelaxNGAddStates(ctxt, res,
                                                              ctxt->state);
                                    ctxt->state = NULL;
                                    if (tmp == 1)
                                        progress = 1;
                                } else if (ctxt->states != NULL) {
                                    for (j = 0; j < ctxt->states->nbState;
                                         j++) {
                                        tmp =
                                            xmlRelaxNGAddStates(ctxt, res,
                                                   ctxt->states->tabState[j]);
                                        if (tmp == 1)
                                            progress = 1;
                                    }
                                    xmlRelaxNGFreeStates(ctxt,
                                                         ctxt->states);
                                    ctxt->states = NULL;
                                }
                            } else {
                                if (ctxt->state != NULL) {
                                    xmlRelaxNGFreeValidState(ctxt,
                                                             ctxt->state);
                                    ctxt->state = NULL;
                                }
                            }
                        }
                    } else {
                        ret = xmlRelaxNGValidateDefinitionList(ctxt,
                                                               define->
                                                               content);
                        if (ret != 0) {
                            xmlRelaxNGFreeValidState(ctxt, ctxt->state);
                            ctxt->state = NULL;
                        } else {
                            base = res->nbState;
                            if (ctxt->state != NULL) {
                                tmp = xmlRelaxNGAddStates(ctxt, res,
                                                          ctxt->state);
                                ctxt->state = NULL;
                                if (tmp == 1)
                                    progress = 1;
                            } else if (ctxt->states != NULL) {
                                for (j = 0; j < ctxt->states->nbState; j++) {
                                    tmp = xmlRelaxNGAddStates(ctxt, res,
                                               ctxt->states->tabState[j]);
                                    if (tmp == 1)
                                        progress = 1;
                                }
                                if (states == NULL) {
                                    states = ctxt->states;
                                } else {
                                    xmlRelaxNGFreeStates(ctxt,
                                                         ctxt->states);
                                }
                                ctxt->states = NULL;
                            }
                        }
                    }
                    if (progress) {
                        /*
                         * Collect all the new nodes added at that step
                         * and make them the new node set
                         */
                        if (res->nbState - base == 1) {
                            ctxt->state = xmlRelaxNGCopyValidState(ctxt,
                                                                   res->
                                                                   tabState
                                                                   [base]);
                        } else {
                            if (states == NULL) {
                                xmlRelaxNGNewStates(ctxt,
                                                    res->nbState - base);
			        states = ctxt->states;
				if (states == NULL) {
				    progress = 0;
				    break;
				}
                            }
                            states->nbState = 0;
                            for (i = base; i < res->nbState; i++)
                                xmlRelaxNGAddStates(ctxt, states,
                                                    xmlRelaxNGCopyValidState
                                                    (ctxt, res->tabState[i]));
                            ctxt->states = states;
                        }
                    }
                } while (progress == 1);
                if (states != NULL) {
                    xmlRelaxNGFreeStates(ctxt, states);
                }
                ctxt->states = res;
                ctxt->flags = oldflags;
#if 0
                /*
                 * errors may have to be propagated back...
                 */
                if (ctxt->errNr > errNr)
                    xmlRelaxNGPopErrors(ctxt, errNr);
#endif
                ret = 0;
                break;
            }
        case XML_RELAXNG_CHOICE:{
                xmlRelaxNGDefinePtr list = NULL;
                xmlRelaxNGStatesPtr states = NULL;

                node = xmlRelaxNGSkipIgnored(ctxt, node);

                errNr = ctxt->errNr;
                if ((define->dflags & IS_TRIABLE) && (define->data != NULL) &&
		    (node != NULL)) {
		    /*
		     * node == NULL can't be optimized since IS_TRIABLE
		     * doesn't account for choice which may lead to
		     * only attributes.
		     */
                    xmlHashTablePtr triage =
                        (xmlHashTablePtr) define->data;

                    /*
                     * Something we can optimize cleanly there is only one
                     * possible branch out !
                     */
                    if ((node->type == XML_TEXT_NODE) ||
                        (node->type == XML_CDATA_SECTION_NODE)) {
                        list =
                            xmlHashLookup2(triage, BAD_CAST "#text", NULL);
                    } else if (node->type == XML_ELEMENT_NODE) {
                        if (node->ns != NULL) {
                            list = xmlHashLookup2(triage, node->name,
                                                  node->ns->href);
                            if (list == NULL)
                                list =
                                    xmlHashLookup2(triage, BAD_CAST "#any",
                                                   node->ns->href);
                        } else
                            list =
                                xmlHashLookup2(triage, node->name, NULL);
                        if (list == NULL)
                            list =
                                xmlHashLookup2(triage, BAD_CAST "#any",
                                               NULL);
                    }
                    if (list == NULL) {
                        ret = -1;
			VALID_ERR2(XML_RELAXNG_ERR_ELEMWRONG, node->name);
                        break;
                    }
                    ret = xmlRelaxNGValidateDefinition(ctxt, list);
                    if (ret == 0) {
                    }
                    break;
                }

                list = define->content;
                oldflags = ctxt->flags;
                ctxt->flags |= FLAGS_IGNORABLE;

                while (list != NULL) {
                    oldstate = xmlRelaxNGCopyValidState(ctxt, ctxt->state);
                    ret = xmlRelaxNGValidateDefinition(ctxt, list);
                    if (ret == 0) {
                        if (states == NULL) {
                            states = xmlRelaxNGNewStates(ctxt, 1);
                        }
                        if (ctxt->state != NULL) {
                            xmlRelaxNGAddStates(ctxt, states, ctxt->state);
                        } else if (ctxt->states != NULL) {
                            for (i = 0; i < ctxt->states->nbState; i++) {
                                xmlRelaxNGAddStates(ctxt, states,
                                                    ctxt->states->
                                                    tabState[i]);
                            }
                            xmlRelaxNGFreeStates(ctxt, ctxt->states);
                            ctxt->states = NULL;
                        }
                    } else {
                        xmlRelaxNGFreeValidState(ctxt, ctxt->state);
                    }
                    ctxt->state = oldstate;
                    list = list->next;
                }
                if (states != NULL) {
                    xmlRelaxNGFreeValidState(ctxt, oldstate);
                    ctxt->states = states;
                    ctxt->state = NULL;
                    ret = 0;
                } else {
                    ctxt->states = NULL;
                }
                ctxt->flags = oldflags;
                if (ret != 0) {
                    if ((ctxt->flags & FLAGS_IGNORABLE) == 0) {
                        xmlRelaxNGDumpValidError(ctxt);
                    }
                } else {
                    if (ctxt->errNr > errNr)
                        xmlRelaxNGPopErrors(ctxt, errNr);
                }
                break;
            }
        case XML_RELAXNG_DEF:
        case XML_RELAXNG_GROUP:
            ret = xmlRelaxNGValidateDefinitionList(ctxt, define->content);
            break;
        case XML_RELAXNG_INTERLEAVE:
            ret = xmlRelaxNGValidateInterleave(ctxt, define);
            break;
        case XML_RELAXNG_ATTRIBUTE:
            ret = xmlRelaxNGValidateAttribute(ctxt, define);
            break;
        case XML_RELAXNG_START:
        case XML_RELAXNG_NOOP:
        case XML_RELAXNG_REF:
        case XML_RELAXNG_EXTERNALREF:
        case XML_RELAXNG_PARENTREF:
            ret = xmlRelaxNGValidateDefinition(ctxt, define->content);
            break;
        case XML_RELAXNG_DATATYPE:{
                xmlNodePtr child;
                xmlChar *content = NULL;

                child = node;
                while (child != NULL) {
                    if (child->type == XML_ELEMENT_NODE) {
                        VALID_ERR2(XML_RELAXNG_ERR_DATAELEM,
                                   node->parent->name);
                        ret = -1;
                        break;
                    } else if ((child->type == XML_TEXT_NODE) ||
                               (child->type == XML_CDATA_SECTION_NODE)) {
                        content = xmlStrcat(content, child->content);
                    }
                    /* TODO: handle entities ... */
                    child = child->next;
                }
                if (ret == -1) {
                    if (content != NULL)
                        xmlFree(content);
                    break;
                }
                if (content == NULL) {
                    content = xmlStrdup(BAD_CAST "");
                    if (content == NULL) {
                        xmlRngVErrMemory(ctxt);
                        ret = -1;
                        break;
                    }
                }
                ret = xmlRelaxNGValidateDatatype(ctxt, content, define,
                                                 ctxt->state->seq);
                if (ret == -1) {
                    VALID_ERR2(XML_RELAXNG_ERR_DATATYPE, define->name);
                } else if (ret == 0) {
                    ctxt->state->seq = NULL;
                }
                if (content != NULL)
                    xmlFree(content);
                break;
            }
        case XML_RELAXNG_VALUE:{
                xmlChar *content = NULL;
                xmlChar *oldvalue;
                xmlNodePtr child;

                child = node;
                while (child != NULL) {
                    if (child->type == XML_ELEMENT_NODE) {
                        VALID_ERR2(XML_RELAXNG_ERR_VALELEM,
                                   node->parent->name);
                        ret = -1;
                        break;
                    } else if ((child->type == XML_TEXT_NODE) ||
                               (child->type == XML_CDATA_SECTION_NODE)) {
                        content = xmlStrcat(content, child->content);
                    }
                    /* TODO: handle entities ... */
                    child = child->next;
                }
                if (ret == -1) {
                    if (content != NULL)
                        xmlFree(content);
                    break;
                }
                if (content == NULL) {
                    content = xmlStrdup(BAD_CAST "");
                    if (content == NULL) {
                        xmlRngVErrMemory(ctxt);
                        ret = -1;
                        break;
                    }
                }
                oldvalue = ctxt->state->value;
                ctxt->state->value = content;
                ret = xmlRelaxNGValidateValue(ctxt, define);
                ctxt->state->value = oldvalue;
                if (ret == -1) {
                    VALID_ERR2(XML_RELAXNG_ERR_VALUE, define->name);
                } else if (ret == 0) {
                    ctxt->state->seq = NULL;
                }
                if (content != NULL)
                    xmlFree(content);
                break;
            }
        case XML_RELAXNG_LIST:{
                xmlChar *content;
                xmlNodePtr child;
                xmlChar *oldvalue, *oldendvalue;
                int len;

                /*
                 * Make sure it's only text nodes
                 */

                content = NULL;
                child = node;
                while (child != NULL) {
                    if (child->type == XML_ELEMENT_NODE) {
                        VALID_ERR2(XML_RELAXNG_ERR_LISTELEM,
                                   node->parent->name);
                        ret = -1;
                        break;
                    } else if ((child->type == XML_TEXT_NODE) ||
                               (child->type == XML_CDATA_SECTION_NODE)) {
                        content = xmlStrcat(content, child->content);
                    }
                    /* TODO: handle entities ... */
                    child = child->next;
                }
                if (ret == -1) {
                    if (content != NULL)
                        xmlFree(content);
                    break;
                }
                if (content == NULL) {
                    content = xmlStrdup(BAD_CAST "");
                    if (content == NULL) {
                        xmlRngVErrMemory(ctxt);
                        ret = -1;
                        break;
                    }
                }
                len = xmlStrlen(content);
                oldvalue = ctxt->state->value;
                oldendvalue = ctxt->state->endvalue;
                ctxt->state->value = content;
                ctxt->state->endvalue = content + len;
                ret = xmlRelaxNGValidateValue(ctxt, define);
                ctxt->state->value = oldvalue;
                ctxt->state->endvalue = oldendvalue;
                if (ret == -1) {
                    VALID_ERR(XML_RELAXNG_ERR_LIST);
                } else if ((ret == 0) && (node != NULL)) {
                    ctxt->state->seq = node->next;
                }
                if (content != NULL)
                    xmlFree(content);
                break;
            }
        case XML_RELAXNG_EXCEPT:
        case XML_RELAXNG_PARAM:
            /* TODO */
            ret = -1;
            break;
    }
    ctxt->depth--;
    return (ret);
}

/**
 * xmlRelaxNGValidateDefinition:
 * @ctxt:  a Relax-NG validation context
 * @define:  the definition to verify
 *
 * Validate the current node lists against the definition
 *
 * Returns 0 if the validation succeeded or an error code.
 */
static int
xmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt,
                             xmlRelaxNGDefinePtr define)
{
    xmlRelaxNGStatesPtr states, res;
    int i, j, k, ret, oldflags;

    /*
     * We should NOT have both ctxt->state and ctxt->states
     */
    if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
        /* TODO */
        xmlRelaxNGFreeValidState(ctxt, ctxt->state);
        ctxt->state = NULL;
    }

    if ((ctxt->states == NULL) || (ctxt->states->nbState == 1)) {
        if (ctxt->states != NULL) {
            ctxt->state = ctxt->states->tabState[0];
            xmlRelaxNGFreeStates(ctxt, ctxt->states);
            ctxt->states = NULL;
        }
        ret = xmlRelaxNGValidateState(ctxt, define);
        if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
            /* TODO */
            xmlRelaxNGFreeValidState(ctxt, ctxt->state);
            ctxt->state = NULL;
        }
        if ((ctxt->states != NULL) && (ctxt->states->nbState == 1)) {
            ctxt->state = ctxt->states->tabState[0];
            xmlRelaxNGFreeStates(ctxt, ctxt->states);
            ctxt->states = NULL;
        }
        return (ret);
    }

    states = ctxt->states;
    ctxt->states = NULL;
    res = NULL;
    j = 0;
    oldflags = ctxt->flags;
    ctxt->flags |= FLAGS_IGNORABLE;
    for (i = 0; i < states->nbState; i++) {
        ctxt->state = states->tabState[i];
        ctxt->states = NULL;
        ret = xmlRelaxNGValidateState(ctxt, define);
        /*
         * We should NOT have both ctxt->state and ctxt->states
         */
        if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
            /* TODO */
            xmlRelaxNGFreeValidState(ctxt, ctxt->state);
            ctxt->state = NULL;
        }
        if (ret == 0) {
            if (ctxt->states == NULL) {
                if (res != NULL) {
                    /* add the state to the container */
                    xmlRelaxNGAddStates(ctxt, res, ctxt->state);
                    ctxt->state = NULL;
                } else {
                    /* add the state directly in states */
                    states->tabState[j++] = ctxt->state;
                    ctxt->state = NULL;
                }
            } else {
                if (res == NULL) {
                    /* make it the new container and copy other results */
                    res = ctxt->states;
                    ctxt->states = NULL;
                    for (k = 0; k < j; k++)
                        xmlRelaxNGAddStates(ctxt, res,
                                            states->tabState[k]);
                } else {
                    /* add all the new results to res and reff the container */
                    for (k = 0; k < ctxt->states->nbState; k++)
                        xmlRelaxNGAddStates(ctxt, res,
                                            ctxt->states->tabState[k]);
                    xmlRelaxNGFreeStates(ctxt, ctxt->states);
                    ctxt->states = NULL;
                }
            }
        } else {
            if (ctxt->state != NULL) {
                xmlRelaxNGFreeValidState(ctxt, ctxt->state);
                ctxt->state = NULL;
            } else if (ctxt->states != NULL) {
                for (k = 0; k < ctxt->states->nbState; k++)
                    xmlRelaxNGFreeValidState(ctxt,
                                             ctxt->states->tabState[k]);
                xmlRelaxNGFreeStates(ctxt, ctxt->states);
                ctxt->states = NULL;
            }
        }
    }
    ctxt->flags = oldflags;
    if (res != NULL) {
        xmlRelaxNGFreeStates(ctxt, states);
        ctxt->states = res;
        ret = 0;
    } else if (j > 1) {
        states->nbState = j;
        ctxt->states = states;
        ret = 0;
    } else if (j == 1) {
        ctxt->state = states->tabState[0];
        xmlRelaxNGFreeStates(ctxt, states);
        ret = 0;
    } else {
        ret = -1;
        xmlRelaxNGFreeStates(ctxt, states);
        if (ctxt->states != NULL) {
            xmlRelaxNGFreeStates(ctxt, ctxt->states);
            ctxt->states = NULL;
        }
    }
    if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
        /* TODO */
        xmlRelaxNGFreeValidState(ctxt, ctxt->state);
        ctxt->state = NULL;
    }
    return (ret);
}

/**
 * xmlRelaxNGValidateDocument:
 * @ctxt:  a Relax-NG validation context
 * @doc:  the document
 *
 * Validate the given document
 *
 * Returns 0 if the validation succeeded or an error code.
 */
static int
xmlRelaxNGValidateDocument(xmlRelaxNGValidCtxtPtr ctxt, xmlDocPtr doc)
{
    int ret;
    xmlRelaxNGPtr schema;
    xmlRelaxNGGrammarPtr grammar;
    xmlRelaxNGValidStatePtr state;
    xmlNodePtr node;

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

    ctxt->errNo = XML_RELAXNG_OK;
    schema = ctxt->schema;
    grammar = schema->topgrammar;
    if (grammar == NULL) {
        VALID_ERR(XML_RELAXNG_ERR_NOGRAMMAR);
        return (-1);
    }
    state = xmlRelaxNGNewValidState(ctxt, NULL);
    ctxt->state = state;
    ret = xmlRelaxNGValidateDefinition(ctxt, grammar->start);
    if ((ctxt->state != NULL) && (state->seq != NULL)) {
        state = ctxt->state;
        node = state->seq;
        node = xmlRelaxNGSkipIgnored(ctxt, node);
        if (node != NULL) {
            if (ret != -1) {
                VALID_ERR(XML_RELAXNG_ERR_EXTRADATA);
                ret = -1;
            }
        }
    } else if (ctxt->states != NULL) {
        int i;
        int tmp = -1;

        for (i = 0; i < ctxt->states->nbState; i++) {
            state = ctxt->states->tabState[i];
            node = state->seq;
            node = xmlRelaxNGSkipIgnored(ctxt, node);
            if (node == NULL)
                tmp = 0;
            xmlRelaxNGFreeValidState(ctxt, state);
        }
        if (tmp == -1) {
            if (ret != -1) {
                VALID_ERR(XML_RELAXNG_ERR_EXTRADATA);
                ret = -1;
            }
        }
    }
    if (ctxt->state != NULL) {
        xmlRelaxNGFreeValidState(ctxt, ctxt->state);
        ctxt->state = NULL;
    }
    if (ret != 0)
        xmlRelaxNGDumpValidError(ctxt);
#ifdef LIBXML_VALID_ENABLED
    if (ctxt->idref == 1) {
        xmlValidCtxt vctxt;

        memset(&vctxt, 0, sizeof(xmlValidCtxt));
        vctxt.valid = 1;

        if (ctxt->error == NULL) {
            vctxt.error = xmlGenericError;
            vctxt.warning = xmlGenericError;
            vctxt.userData = xmlGenericErrorContext;
        } else {
            vctxt.error = ctxt->error;
            vctxt.warning = ctxt->warning;
            vctxt.userData = ctxt->userData;
        }

        if (xmlValidateDocumentFinal(&vctxt, doc) != 1)
            ret = -1;
    }
#endif /* LIBXML_VALID_ENABLED */
    if ((ret == 0) && (ctxt->errNo != XML_RELAXNG_OK))
        ret = -1;

    return (ret);
}

/**
 * xmlRelaxNGCleanPSVI:
 * @node:  an input element or document
 *
 * Call this routine to speed up XPath computation on static documents.
 * This stamps all the element nodes with the document order
 * Like for line information, the order is kept in the element->content
 * field, the value stored is actually - the node number (starting at -1)
 * to be able to differentiate from line numbers.
 *
 * Returns the number of elements found in the document or -1 in case
 *    of error.
 */
static void
xmlRelaxNGCleanPSVI(xmlNodePtr node) {
    xmlNodePtr cur;

    if ((node == NULL) ||
        ((node->type != XML_ELEMENT_NODE) &&
         (node->type != XML_DOCUMENT_NODE) &&
         (node->type != XML_HTML_DOCUMENT_NODE)))
	return;
    if (node->type == XML_ELEMENT_NODE)
        node->psvi = NULL;

    cur = node->children;
    while (cur != NULL) {
	if (cur->type == XML_ELEMENT_NODE) {
	    cur->psvi = NULL;
	    if (cur->children != NULL) {
		cur = cur->children;
		continue;
	    }
	}
	if (cur->next != NULL) {
	    cur = cur->next;
	    continue;
	}
	do {
	    cur = cur->parent;
	    if (cur == NULL)
		break;
	    if (cur == node) {
		cur = NULL;
		break;
	    }
	    if (cur->next != NULL) {
		cur = cur->next;
		break;
	    }
	} while (cur != NULL);
    }
    return;
}
/************************************************************************
 *									*
 *			Validation interfaces				*
 *									*
 ************************************************************************/

/**
 * xmlRelaxNGNewValidCtxt:
 * @schema:  a precompiled XML RelaxNGs
 *
 * Create an XML RelaxNGs validation context based on the given schema
 *
 * Returns the validation context or NULL in case of error
 */
xmlRelaxNGValidCtxtPtr
xmlRelaxNGNewValidCtxt(xmlRelaxNGPtr schema)
{
    xmlRelaxNGValidCtxtPtr ret;

    ret = (xmlRelaxNGValidCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGValidCtxt));
    if (ret == NULL) {
        xmlRngVErrMemory(NULL);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlRelaxNGValidCtxt));
    ret->schema = schema;
    ret->errNr = 0;
    ret->errMax = 0;
    ret->err = NULL;
    ret->errTab = NULL;
    if (schema != NULL)
	ret->idref = schema->idref;
    ret->states = NULL;
    ret->freeState = NULL;
    ret->freeStates = NULL;
    ret->errNo = XML_RELAXNG_OK;
    return (ret);
}

/**
 * xmlRelaxNGFreeValidCtxt:
 * @ctxt:  the schema validation context
 *
 * Free the resources associated to the schema validation context
 */
void
xmlRelaxNGFreeValidCtxt(xmlRelaxNGValidCtxtPtr ctxt)
{
    int k;

    if (ctxt == NULL)
        return;
    if (ctxt->states != NULL)
        xmlRelaxNGFreeStates(NULL, ctxt->states);
    if (ctxt->freeState != NULL) {
        for (k = 0; k < ctxt->freeState->nbState; k++) {
            xmlRelaxNGFreeValidState(NULL, ctxt->freeState->tabState[k]);
        }
        xmlRelaxNGFreeStates(NULL, ctxt->freeState);
    }
    if (ctxt->freeStates != NULL) {
        for (k = 0; k < ctxt->freeStatesNr; k++) {
            xmlRelaxNGFreeStates(NULL, ctxt->freeStates[k]);
        }
        xmlFree(ctxt->freeStates);
    }
    if (ctxt->errTab != NULL)
        xmlFree(ctxt->errTab);
    if (ctxt->elemTab != NULL) {
        xmlRegExecCtxtPtr exec;

        exec = xmlRelaxNGElemPop(ctxt);
        while (exec != NULL) {
            xmlRegFreeExecCtxt(exec);
            exec = xmlRelaxNGElemPop(ctxt);
        }
        xmlFree(ctxt->elemTab);
    }
    xmlFree(ctxt);
}

/**
 * xmlRelaxNGSetValidErrors:
 * @ctxt:  a Relax-NG validation context
 * @err:  the error function
 * @warn: the warning function
 * @ctx: the functions context
 *
 * DEPRECATED: Use xmlRelaxNGSetValidStructuredErrors.
 *
 * Set the error and warning callback information
 */
void
xmlRelaxNGSetValidErrors(xmlRelaxNGValidCtxtPtr ctxt,
                         xmlRelaxNGValidityErrorFunc err,
                         xmlRelaxNGValidityWarningFunc warn, void *ctx)
{
    if (ctxt == NULL)
        return;
    ctxt->error = err;
    ctxt->warning = warn;
    ctxt->userData = ctx;
    ctxt->serror = NULL;
}

/**
 * xmlRelaxNGSetValidStructuredErrors:
 * @ctxt:  a Relax-NG validation context
 * @serror:  the structured error function
 * @ctx: the functions context
 *
 * Set the structured error callback
 */
void
xmlRelaxNGSetValidStructuredErrors(xmlRelaxNGValidCtxtPtr ctxt,
                                   xmlStructuredErrorFunc serror, void *ctx)
{
    if (ctxt == NULL)
        return;
    ctxt->serror = serror;
    ctxt->error = NULL;
    ctxt->warning = NULL;
    ctxt->userData = ctx;
}

/**
 * xmlRelaxNGGetValidErrors:
 * @ctxt:  a Relax-NG validation context
 * @err:  the error function result
 * @warn: the warning function result
 * @ctx: the functions context result
 *
 * Get the error and warning callback information
 *
 * Returns -1 in case of error and 0 otherwise
 */
int
xmlRelaxNGGetValidErrors(xmlRelaxNGValidCtxtPtr ctxt,
                         xmlRelaxNGValidityErrorFunc * err,
                         xmlRelaxNGValidityWarningFunc * warn, void **ctx)
{
    if (ctxt == NULL)
        return (-1);
    if (err != NULL)
        *err = ctxt->error;
    if (warn != NULL)
        *warn = ctxt->warning;
    if (ctx != NULL)
        *ctx = ctxt->userData;
    return (0);
}

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

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

    ctxt->doc = doc;

    ret = xmlRelaxNGValidateDocument(ctxt, doc);
    /*
     * Remove all left PSVI
     */
    xmlRelaxNGCleanPSVI((xmlNodePtr) doc);

    /*
     * TODO: build error codes
     */
    if (ret == -1)
        return (1);
    return (ret);
}

#endif /* LIBXML_SCHEMAS_ENABLED */
