/*
 * 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 <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>

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

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


/* #define DEBUG 1 */
/* #define DEBUG_GRAMMAR 1 */
/* #define DEBUG_CONTENT 1 */
/* #define DEBUG_TYPE 1 */
/* #define DEBUG_VALID 1 */
/* #define DEBUG_INTERLEAVE 1 */
/* #define DEBUG_LIST 1 */
/* #define DEBUG_INCLUDE */
/* #define DEBUG_ERROR 1 */
/* #define DEBUG_COMPILE 1 */
/* #define DEBUG_PROGRESSIVE 1 */

#define MAX_ERROR 5

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

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,	/* extenal data type definition */
    XML_RELAXNG_PARAM,		/* extenal data type parameter */
    XML_RELAXNG_VALUE,		/* value from an extenal data type definition */
    XML_RELAXNG_LIST,		/* a list of patterns */
    XML_RELAXNG_ATTRIBUTE,	/* an attrbute 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)

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 */
    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 aloocated */
    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 */
};

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

/**
 * 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 */

    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 */
};

/**
 * 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 */
};


/************************************************************************
 * 									*
 * 		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) {
        if ((ctxt != NULL) && (ctxt->error != NULL))
            ctxt->error(ctxt->userData, "Out of memory\n");
	ctxt->nbErrors++;
        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) {
        if ((ctxt != NULL) && (ctxt->error != NULL))
            ctxt->error(ctxt->userData, "Out of memory\n");
	ctxt->nbErrors++;
        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) {
	    if ((ctxt != NULL) && (ctxt->error != NULL))
		ctxt->error(ctxt->userData, "Out of memory\n");
	    ctxt->nbErrors++;
	    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) {
	    if ((ctxt != NULL) && (ctxt->error != NULL))
		ctxt->error(ctxt->userData, "Out of memory\n");
	    ctxt->nbErrors++;
	    return (NULL);
	}
	ctxt->defTab = tmp;
    }
    ret = (xmlRelaxNGDefinePtr) xmlMalloc(sizeof(xmlRelaxNGDefine));
    if (ret == NULL) {
	if ((ctxt != NULL) && (ctxt->error != NULL))
	    ctxt->error(ctxt->userData, "Out of memory\n");
	ctxt->nbErrors++;
	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->freeState != 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) {
        if ((ctxt != NULL) && (ctxt->error != NULL))
            ctxt->error(ctxt->userData, "Out of memory\n");
        return (NULL);
    }
    ret->nbState = 0;
    ret->maxState = size;
    ret->tabState = (xmlRelaxNGValidStatePtr *) xmlMalloc(
	                    (size) * sizeof(xmlRelaxNGValidStatePtr));
    if (ret->tabState == NULL) {
        if ((ctxt != NULL) && (ctxt->error != NULL))
            ctxt->error(ctxt->userData, "Out of memory\n");
	xmlFree(ret->tabState);
        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) {
	    if ((ctxt != NULL) && (ctxt->error != NULL))
		ctxt->error(ctxt->userData, "Out of memory\n");
	    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) {
	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) {
	    if ((ctxt != NULL) && (ctxt->error != NULL))
		ctxt->error(ctxt->userData, "Out of memory\n");
	    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:  teh 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) {
	    if ((ctxt != NULL) && (ctxt->error != NULL))
		ctxt->error(ctxt->userData, "Out of memory\n");
	}
    } else if ((ctxt != NULL) && (ctxt->freeStatesNr >= ctxt->freeStatesMax)) {
	xmlRelaxNGStatesPtr *tmp;

	tmp = (xmlRelaxNGStatesPtr *) xmlRealloc(ctxt->freeStates,
		2 * ctxt->freeStatesMax * sizeof(xmlRelaxNGStatesPtr));
	if (tmp == NULL) {
	    if ((ctxt != NULL) && (ctxt->error != NULL))
		ctxt->error(ctxt->userData, "Out of memory\n");
	    xmlFree(states->tabState);
	    xmlFree(states);
	    return;
	}
	ctxt->freeStates = tmp;
	ctxt->freeStatesMax *= 2;
    }
    if ((ctxt == NULL) || (ctxt->freeState == 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) {
	    if ((ctxt != NULL) && (ctxt->error != NULL))
		ctxt->error(ctxt->userData, "Out of memory\n");
	    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) {
		if ((ctxt != NULL) && (ctxt->error != NULL))
		    ctxt->error(ctxt->userData, "Out of memory\n");
		return (ret);
	    }
	} else if (ret->maxAttrs < nbAttrs) {
	    xmlAttrPtr *tmp;

	    tmp = (xmlAttrPtr *) xmlRealloc(ret->attrs, nbAttrs *
		                          sizeof(xmlAttrPtr));
	    if (tmp == NULL) {
		if ((ctxt != NULL) && (ctxt->error != NULL))
		    ctxt->error(ctxt->userData, "Out of memory\n");
		return (ret);
	    }
	    ret->attrs = tmp;
	}
	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) {
	    if ((ctxt != NULL) && (ctxt->error != NULL))
		ctxt->error(ctxt->userData, "Out of memory\n");
	    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) {
		if ((ctxt != NULL) && (ctxt->error != NULL))
		    ctxt->error(ctxt->userData, "Out of memory\n");
		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) {
		if ((ctxt != NULL) && (ctxt->error != NULL))
		    ctxt->error(ctxt->userData, "Out of memory\n");
		ret->nbAttrs = 0;
		return (ret);
	    }
	    ret->maxAttrs = state->maxAttrs;
	}
	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 equald, 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);
    }
}

/************************************************************************
 * 									*
 * 			Document functions					*
 * 									*
 ************************************************************************/
static xmlDocPtr xmlRelaxNGCleanupDoc(xmlRelaxNGParserCtxtPtr ctxt,
	                              xmlDocPtr 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) {
            xmlGenericError(xmlGenericErrorContext, "malloc failed !\n");
            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) {
            xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
            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 (0);
    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] = 0;
    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;

#ifdef DEBUG_INCLUDE
    if (name == NULL)
	xmlGenericError(xmlGenericErrorContext,
		    "Elimination of <include> start from %s\n", URL);
    else
	xmlGenericError(xmlGenericErrorContext,
		"Elimination of <include> define %s from %s\n", name, URL);
#endif
    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->_private;

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

		if (xmlStrEqual(inc->doc->children->name, BAD_CAST "grammar")) {
#ifdef DEBUG_INCLUDE
		    href = xmlGetProp(tmp, BAD_CAST "href");
#endif
		    if (xmlRelaxNGRemoveRedefine(ctxt, href,
				inc->doc->children->children, name) == 1) {
			found = 1;
		    }
		    if (href != NULL)
			xmlFree(href);
		}
	    }
	}
	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;

#ifdef DEBUG_INCLUDE
    xmlGenericError(xmlGenericErrorContext,
		    "xmlRelaxNGLoadInclude(%s)\n", URL);
#endif

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

    /*
     * load the document
     */
    doc = xmlParseFile((const char *) URL);
    if (doc == NULL) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
			"xmlRelaxNG: could not load %s\n", URL);
	ctxt->nbErrors++;
	return (NULL);
    }

#ifdef DEBUG_INCLUDE
    xmlGenericError(xmlGenericErrorContext,
		    "Parsed %s Okay\n", URL);
#endif

    /*
     * Allocate the document structures and register it first.
     */
    ret = (xmlRelaxNGIncludePtr) xmlMalloc(sizeof(xmlRelaxNGInclude));
    if (ret == NULL) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
			"xmlRelaxNG: allocate memory for doc %s\n", URL);
	ctxt->nbErrors++;
	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.
     */
#ifdef DEBUG_INCLUDE
    xmlGenericError(xmlGenericErrorContext,
		    "cleanup of %s\n", URL);
#endif

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

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

#ifdef DEBUG_INCLUDE
    xmlGenericError(xmlGenericErrorContext,
		    "Checking of %s\n", URL);
#endif
    /*
     * Check that the top element is a grammar
     */
    root = xmlDocGetRootElement(doc);
    if (root == NULL) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
			"xmlRelaxNG: included document is empty %s\n", URL);
	ctxt->nbErrors++;
	return (NULL);
    }
    if (!IS_RELAXNG(root, "grammar")) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
		    "xmlRelaxNG: included document %s root is not a grammar\n",
		        URL);
	ctxt->nbErrors++;
	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) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
	"xmlRelaxNG: include %s has a start but not the included grammar\n",
				URL);
		ctxt->nbErrors++;
	    }
	} else if (IS_RELAXNG(cur, "define")) {
	    xmlChar *name;

	    name = xmlGetProp(cur, BAD_CAST "name");
	    if (name == NULL) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			    "xmlRelaxNG: include %s has define without name\n",
				URL);
		ctxt->nbErrors++;
	    } else {
		int found;

		xmlRelaxNGNormExtSpace(name);
		found = xmlRelaxNGRemoveRedefine(ctxt, URL,
			                         root->children, name);
		if (!found) {
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
    "xmlRelaxNG: include %s has a define %s but not the included grammar\n",
				    URL, name);
		    ctxt->nbErrors++;
		}
		xmlFree(name);
	    }
	}
	cur = cur->next;
    }


    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;
#ifdef DEBUG_ERROR
    xmlGenericError(xmlGenericErrorContext,
	    "Pushing error %d at %d on stack\n", err, ctxt->errNr);
#endif
    if (ctxt->errTab == NULL) {
	ctxt->errMax = 8;
	ctxt->errNr = 0;
	ctxt->errTab = (xmlRelaxNGValidErrorPtr) xmlMalloc(
		        ctxt->errMax * sizeof(xmlRelaxNGValidError));
        if (ctxt->errTab == NULL) {
            xmlGenericError(xmlGenericErrorContext, "malloc failed !\n");
            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) {
            xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
            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) {
            xmlGenericError(xmlGenericErrorContext, "malloc failed !\n");
            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) {
            xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
            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 (0);
    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] = 0;
    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)) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
		    "Detected an externalRef recursion for %s\n",
			    URL);
	    ctxt->nbErrors++;
	    return(NULL);
	}
    }

    /*
     * load the document
     */
    doc = xmlParseFile((const char *) URL);
    if (doc == NULL) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
			"xmlRelaxNG: could not load %s\n", URL);
	ctxt->nbErrors++;
	return (NULL);
    }

    /*
     * Allocate the document structures and register it first.
     */
    ret = (xmlRelaxNGDocumentPtr) xmlMalloc(sizeof(xmlRelaxNGDocument));
    if (ret == NULL) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
			"xmlRelaxNG: allocate memory for doc %s\n", URL);
	ctxt->nbErrors++;
	xmlFreeDoc(doc);
	return (NULL);
    }
    memset(ret, 0, sizeof(xmlRelaxNGDocument));
    ret->doc = doc;
    ret->href = xmlStrdup(URL);
    ret->next = ctxt->documents;
    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];

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

/**
 * xmlRelaxNGValidErrorContext:
 * @ctxt:  the validation context
 * @node:  the node
 * @child:  the node child generating the problem.
 *
 * Dump informations about the kocation of the error in the instance
 */
static void
xmlRelaxNGValidErrorContext(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node,
	                    xmlNodePtr child)
{
    int line = 0;
    const xmlChar *file = NULL;
    const xmlChar *name = NULL;
    const char *type = "error";

    if ((ctxt == NULL) || (ctxt->error == NULL))
	return;

    if (child != NULL)
	node = child;

    if (node != NULL)  {
	if ((node->type == XML_DOCUMENT_NODE) ||
	    (node->type == XML_HTML_DOCUMENT_NODE)) {
	    xmlDocPtr doc = (xmlDocPtr) node;

	    file = doc->URL;
	} else {
	    /*
	     * Try to find contextual informations to report
	     */
	    if (node->type == XML_ELEMENT_NODE) {
		line = (int) node->content;
	    } else if ((node->prev != NULL) &&
		       (node->prev->type == XML_ELEMENT_NODE)) {
		line = (int) node->prev->content;
	    } else if ((node->parent != NULL) &&
		       (node->parent->type == XML_ELEMENT_NODE)) {
		line = (int) node->parent->content;
	    }
	    if ((node->doc != NULL) && (node->doc->URL != NULL))
		file = node->doc->URL;
	    if (node->name != NULL)
		name = node->name;
	}
    } 
    
    type = "RNG validity error";

    if ((file != NULL) && (line != 0) && (name != NULL))
	ctxt->error(ctxt->userData, "%s: file %s line %d element %s\n",
		type, file, line, name);
    else if ((file != NULL) && (name != NULL))
	ctxt->error(ctxt->userData, "%s: file %s element %s\n",
		type, file, name);
    else if ((file != NULL) && (line != 0))
	ctxt->error(ctxt->userData, "%s: file %s line %d\n", type, file, line);
    else if (file != NULL)
	ctxt->error(ctxt->userData, "%s: file %s\n", type, file);
    else if (name != NULL)
	ctxt->error(ctxt->userData, "%s: element %s\n", type, name);
    else
	ctxt->error(ctxt->userData, "%s\n", type);
}

/**
 * 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->error == NULL)
        return;

#ifdef DEBUG_ERROR
    xmlGenericError(xmlGenericErrorContext,
	    "Show error %d\n", err);
#endif
    msg = xmlRelaxNGGetErrorString(err, arg1, arg2);
    if (msg == NULL)
	return;

    if (ctxt->errNo == XML_RELAXNG_OK)
	ctxt->errNo = err;
    xmlRelaxNGValidErrorContext(ctxt, node, child);
    ctxt->error(ctxt->userData, "%s\n", msg);
    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;

#ifdef DEBUG_ERROR
    xmlGenericError(xmlGenericErrorContext,
	    "Pop errors till level %d\n", level);
#endif
    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;

#ifdef DEBUG_ERROR
    xmlGenericError(xmlGenericErrorContext,
	    "Dumping error stack %d errors\n", ctxt->errNr);
#endif
    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) || (ctxt->error == NULL))
	return;

#ifdef DEBUG_ERROR
    xmlGenericError(xmlGenericErrorContext,
	    "Adding error %d\n", err);
#endif
    /*
     * generate the error directly
     */
    if (((ctxt->flags & 1) == 0) || (ctxt->flags & 2)) {
	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;
	}
	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 = xmlStrdup(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) {
	xmlSchemaFreeValue(res1);
	return(-1);
    }
    if (res1 == NULL) {
	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(xmlRelaxNGTypeLibraryPtr lib,
	                  const xmlChar *namespace ATTRIBUTE_UNUSED) {
    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) {
	xmlGenericError(xmlGenericErrorContext,
		"Relax-NG types library '%s' already registered\n",
		        namespace);
	return(-1);
    }
    lib = (xmlRelaxNGTypeLibraryPtr) xmlMalloc(sizeof(xmlRelaxNGTypeLibrary));
    if (lib == NULL) {
	xmlGenericError(xmlGenericErrorContext,
		"Relax-NG types library '%s' malloc() failed\n",
		        namespace);
        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) {
	xmlGenericError(xmlGenericErrorContext,
		"Relax-NG types library failed to register '%s'\n",
		        namespace);
	xmlRelaxNGFreeTypeLibrary(lib, namespace);
	return(-1);
    }
    return(0);
}

/**
 * xmlRelaxNGInitTypes:
 *
 * Initilize the default type libraries.
 *
 * Returns 0 in case of success and -1 in case of error.
 */
static int
xmlRelaxNGInitTypes(void) {
    if (xmlRelaxNGTypeInitialized != 0)
	return(0);
    xmlRelaxNGRegisteredTypes = xmlHashCreate(10);
    if (xmlRelaxNGRegisteredTypes == NULL) {
	xmlGenericError(xmlGenericErrorContext,
		"Failed to allocate sh table for Relax-NG types\n");
	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:
 *
 * Cleanup the default Schemas type library associated to RelaxNG
 */
void	
xmlRelaxNGCleanupTypes(void) {
    if (xmlRelaxNGTypeInitialized == 0)
	return;
    xmlSchemaCleanupTypes();
    xmlHashFree(xmlRelaxNGRegisteredTypes, (xmlHashDeallocator)
	        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);

/**
 * xmlRelaxNGIsCompileable:
 * @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
xmlRelaxNGIsCompileable(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_REF:
        case XML_RELAXNG_EXTERNALREF:
        case XML_RELAXNG_PARENTREF:
	    if (def->depth == -20) {
	        return(1);
	    } else {
	        def->depth = -20;
		ret = xmlRelaxNGIsCompileable(def->content);
	    }
	    break;
        case XML_RELAXNG_NOOP:
        case XML_RELAXNG_START:
	    ret = xmlRelaxNGIsCompileable(def->content);
	    break;
        case XML_RELAXNG_TEXT:
        case XML_RELAXNG_EMPTY:
	    ret = 1;
	    break;
        case XML_RELAXNG_ELEMENT:
	    if (((def->dflags & IS_NOT_COMPILABLE) == 0) &&
	        ((def->dflags & IS_COMPILABLE) == 0)) {
		ret = xmlRelaxNGIsCompileable(def->content);
		if (ret == 0) def->dflags |= IS_NOT_COMPILABLE;
		if (ret == 1) def->dflags |= IS_COMPILABLE;
	    }
	    if ((def->nameClass != NULL) || (def->name == NULL))
	        return(0);
	    else
		return(1);
	    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: {
	    xmlRelaxNGDefinePtr list;

	    list = def->content;
	    while (list != NULL) {
		ret = xmlRelaxNGIsCompileable(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:
	    ret = 0;
	    break;
        case XML_RELAXNG_NOT_ALLOWED:
	    ret = -1;
	    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 ((xmlRelaxNGIsCompileable(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);
		ctxt->state = xmlAutomataGetInitState(ctxt->am);
		while (list != NULL) {
		    xmlRelaxNGCompile(ctxt, list);
		    list = list->next;
		}
		xmlAutomataSetFinalState(ctxt->am, ctxt->state);
		def->contModel = xmlAutomataCompile(ctxt->am);
		xmlRegexpIsDeterminist(def->contModel);

		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);
		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_REF:
        case XML_RELAXNG_EXTERNALREF:
        case XML_RELAXNG_PARENTREF:
        case XML_RELAXNG_NOOP:
	    ret = xmlRelaxNGCompile(ctxt, def->content);
	    break;
        case XML_RELAXNG_OPTIONAL: {
	    xmlAutomataStatePtr oldstate = ctxt->state;
	    
	    xmlRelaxNGCompile(ctxt, def->content);
	    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;
		xmlRelaxNGCompile(ctxt, list);
		if (target == NULL)
		    target = ctxt->state;
		else {
		    xmlAutomataNewEpsilon(ctxt->am, ctxt->state, target);
		}
		list = list->next;
	    }
	    ctxt->state = target;

	    break;
	}
        case XML_RELAXNG_GROUP:
        case XML_RELAXNG_DEF:
	    list = def->content;
	    while (list != NULL) {
		xmlRelaxNGCompile(ctxt, list);
		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 = xmlRelaxNGIsCompileable(def);
	if ((def->dflags & IS_COMPILABLE) && (def->depth != -25)) {
	    ctxt->am = NULL;
	    ret = xmlRelaxNGCompile(ctxt, def);
	    return(ret);
	}
    }
    switch(def->type) {
        case XML_RELAXNG_REF:
        case XML_RELAXNG_EXTERNALREF:
        case XML_RELAXNG_PARENTREF:
        case XML_RELAXNG_NOOP:
        case XML_RELAXNG_START:
	    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:
	    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(*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 datatypeLibary value or NULL if not found
 */
static xmlChar *
xmlRelaxNGGetDataTypeLibrary(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
	                     xmlNodePtr node) {
    xmlChar *ret, *escape;

    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)) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
		    "value type '%s' is not an NCName\n",
			    type);
	    ctxt->nbErrors++;
	}
	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) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
		    "Use of unregistered type library '%s'\n",
			    library);
	    ctxt->nbErrors++;
	    def->data = NULL;
	} else {
	    def->data = lib;
	    if (lib->have == NULL) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
		    "Internal error with type library '%s': no 'have'\n",
			    library);
		ctxt->nbErrors++;
	    } else {
		success = lib->have(lib->data, def->name);
		if (success != 1) {
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
		    "Error type '%s' is not exported by type library '%s'\n",
				def->name, library);
		    ctxt->nbErrors++;
		}
	    }
	}
    }
    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)) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
		"Expecting a single text value for <value>content\n");
	ctxt->nbErrors++;
    } else if (def != NULL) {
	def->value = xmlNodeGetContent(node);
	if (def->value == NULL) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			    "Element <value> has no content\n");
	    ctxt->nbErrors++;
	} 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) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Value '%s' is not acceptable for type '%s'\n",
			        def->value, def->name);
		ctxt->nbErrors++;
	    } 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, last = NULL;
    xmlRelaxNGDefinePtr param, lastparam = NULL;
    xmlRelaxNGTypeLibraryPtr lib;
    xmlChar *type;
    xmlChar *library;
    xmlNodePtr content;
    int tmp;

    type = xmlGetProp(node, BAD_CAST "type");
    if (type == NULL) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
			"data has no type\n");
	ctxt->nbErrors++;
	return(NULL);
    }
    xmlRelaxNGNormExtSpace(type);
    if (xmlValidateNCName(type, 0)) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
		"data type '%s' is not an NCName\n",
			type);
	ctxt->nbErrors++;
    }
    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(type);
	return(NULL);
    }
    def->type = XML_RELAXNG_DATATYPE;
    def->name = type;
    def->ns = library;

    lib = (xmlRelaxNGTypeLibraryPtr)
	xmlHashLookup(xmlRelaxNGRegisteredTypes, library);
    if (lib == NULL) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
		"Use of unregistered type library '%s'\n",
		        library);
	ctxt->nbErrors++;
	def->data = NULL;
    } else {
	def->data = lib;
	if (lib->have == NULL) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
		"Internal error with type library '%s': no 'have'\n",
		        library);
	    ctxt->nbErrors++;
	} else {
	    tmp = lib->have(lib->data, def->name);
	    if (tmp != 1) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
		    "Error type '%s' is not exported by type library '%s'\n",
			    def->name, library);
		ctxt->nbErrors++;
	    } 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")) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
		"Type library '%s' does not allow type parameters\n",
			    library);
	    ctxt->nbErrors++;
	    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) {
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
			    "param has no name\n");
		    ctxt->nbErrors++;
		}
		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, last2 = NULL;

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

    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 disttinct, 0 if equal
 */
static int
xmlRelaxNGCompareNameClasses(xmlRelaxNGDefinePtr def1,
	                     xmlRelaxNGDefinePtr def2) {
    int ret = 1;
    xmlNode node;
    xmlNs ns;
    xmlRelaxNGValidCtxt ctxt;
    ctxt.flags = FLAGS_IGNORABLE;

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

    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;
	}
	node.ns = &ns;
	if (def1->ns != NULL) {
	    if (def1->ns[0] == 0) {
		node.ns = NULL;
	    } else {
		ns.href = def1->ns;
	    }
	} else {
	    ns.href = invalidName;
	}
        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) {
	TODO
	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 disttinct, 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) or attributes (1)
 *
 * 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))) {
	    if (ret == NULL) {
		max = 10;
		ret = (xmlRelaxNGDefinePtr *)
		    xmlMalloc((max + 1) * sizeof(xmlRelaxNGDefinePtr));
		if (ret == NULL) {
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
			    "Out of memory in element search\n");
		    ctxt->nbErrors++;
		    return(NULL);
		}
	    } else if (max <= len) {
		max *= 2;
		ret = xmlRealloc(ret, (max + 1) * sizeof(xmlRelaxNGDefinePtr));
		if (ret == NULL) {
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
			    "Out of memory in element search\n");
		    ctxt->nbErrors++;
		    return(NULL);
		}
	    }
	    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)) {
	    /*
	     * 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) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
		"Out of memory in choice computation\n");
	ctxt->nbErrors++;
	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) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
		"Out of memory in group computation\n");
	ctxt->nbErrors++;
	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) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Attributes conflicts in group\n");
		ctxt->nbErrors++;
	    }
	}
    }
    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(xmlRelaxNGDefinePtr def,
	                     xmlRelaxNGParserCtxtPtr ctxt,
			     xmlChar *name ATTRIBUTE_UNUSED) {
    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;

#ifdef DEBUG_INTERLEAVE
    xmlGenericError(xmlGenericErrorContext,
		    "xmlRelaxNGComputeInterleaves(%s)\n",
		    name);
#endif
    cur = def->content;
    while (cur != NULL) {
	nbchild++;
	cur = cur->next;
    }
    
#ifdef DEBUG_INTERLEAVE
    xmlGenericError(xmlGenericErrorContext, "  %d child\n", nbchild);
#endif
    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, 0);
	groups[nbgroups]->attrs = xmlRelaxNGGetElements(ctxt, cur, 1);
	nbgroups++;
	cur = cur->next;
    }
#ifdef DEBUG_INTERLEAVE
    xmlGenericError(xmlGenericErrorContext, "  %d groups\n", nbgroups);
#endif

    /*
     * 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) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Element or text conflicts in interleave\n");
		ctxt->nbErrors++;
	    }
	    ret = xmlRelaxNGCompareElemDefLists(ctxt, group->attrs,
						groups[j]->attrs);
	    if (ret == 0) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Attributes conflicts in interleave\n");
		ctxt->nbErrors++;
	    }
	}
	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 *)(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 *)(i + 1));
		    else
			res = xmlHashAddEntry2(partitions->triage,
				       (*tmp)->name, (*tmp)->ns,
				       (void *)(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 *)(i + 1));
		    else
			res = xmlHashAddEntry2(partitions->triage,
				       BAD_CAST "#any", (*tmp)->ns,
				       (void *)(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:
    if (ctxt->error != NULL)
	ctxt->error(ctxt->userData,
	    "Out of memory in interleave computation\n");
    ctxt->nbErrors++;
    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) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
		"Failed to create interleaves hash table\n");
	ctxt->nbErrors++;
    } else {
	char name[32];

	snprintf(name, 32, "interleave%d", ctxt->nbInterleaves++);
	if (xmlHashAddEntry(ctxt->interleaves, BAD_CAST name, def) < 0) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
		    "Failed to add %s to hash table\n", name);
	    ctxt->nbErrors++;
	}
    }
    child = node->children;
    if (child == NULL) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData, "Element interleave is empty\n");
	ctxt->nbErrors++;
    }
    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->_private;
    if (incl == NULL) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
		"Include node has no data\n");
	ctxt->nbErrors++;
	return(-1);
    }
    root = xmlDocGetRootElement(incl->doc);
    if (root == NULL) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
		"Include document is empty\n");
	ctxt->nbErrors++;
	return(-1);
    }
    if (!xmlStrEqual(root->name, BAD_CAST "grammar")) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
		"Include document root is not a grammar\n");
	ctxt->nbErrors++;
	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) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
			"define has no name\n");
	ctxt->nbErrors++;
    } else {
	xmlRelaxNGNormExtSpace(name);
	if (xmlValidateNCName(name, 0)) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
		    "define name '%s' is not an NCName\n",
			    name);
	    ctxt->nbErrors++;
	}
	def = xmlRelaxNGNewDefine(ctxt, node);
	if (def == NULL) {
	    xmlFree(name);
	    return(-1);
	}
	def->type = XML_RELAXNG_DEF;
	def->name = name;
	if (node->children == NULL) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			    "define has no children\n");
	    ctxt->nbErrors++;
	} 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) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			    "Could not create definition hash\n");
	    ctxt->nbErrors++;
	    ret = -1;
	} else {
	    tmp = xmlHashAddEntry(ctxt->grammar->defs, name, def);
	    if (tmp < 0) {
		xmlRelaxNGDefinePtr prev;

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

/**
 * xmlRelaxNGProcessExternalRef:
 * @ctxt: the parser context
 * @node:  the externlRef node
 *
 * Process and compile an externlRef 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->_private;
    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) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			    "xmlRelaxNGParse: %s is empty\n",
				ctxt->URL);
		ctxt->nbErrors++;
		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;
	    }

	    /*
	     * 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) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData, "empty: had a child node\n");
	    ctxt->nbErrors++;
	}
    } else if (IS_RELAXNG(node, "text")) {
	def = xmlRelaxNGNewDefine(ctxt, node);
	if (def == NULL)
	    return(NULL);
	def->type = XML_RELAXNG_TEXT;
	if (node->children != NULL) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData, "text: had a child node\n");
	    ctxt->nbErrors++;
	}
    } else if (IS_RELAXNG(node, "zeroOrMore")) {
	def = xmlRelaxNGNewDefine(ctxt, node);
	if (def == NULL)
	    return(NULL);
	def->type = XML_RELAXNG_ZEROORMORE;
	if (node->children == NULL) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			    "Element %s is empty\n", node->name);
	    ctxt->nbErrors++;
	} 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) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			    "Element %s is empty\n", node->name);
	    ctxt->nbErrors++;
	} 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) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			    "Element %s is empty\n", node->name);
	    ctxt->nbErrors++;
	} 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) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			    "Element %s is empty\n", node->name);
	    ctxt->nbErrors++;
	} 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) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			    "Element %s is empty\n", node->name);
	    ctxt->nbErrors++;
	} 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) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			    "ref has no name\n");
	    ctxt->nbErrors++;
	} else {
	    xmlRelaxNGNormExtSpace(def->name);
	    if (xmlValidateNCName(def->name, 0)) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"ref name '%s' is not an NCName\n",
				def->name);
		ctxt->nbErrors++;
	    }
	}
	if (node->children != NULL) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			    "ref is not empty\n");
	    ctxt->nbErrors++;
	}
	if (ctxt->grammar->refs == NULL)
	    ctxt->grammar->refs = xmlHashCreate(10);
	if (ctxt->grammar->refs == NULL) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			    "Could not create references hash\n");
	    ctxt->nbErrors++;
	    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) {
			if (ctxt->error != NULL)
			    ctxt->error(ctxt->userData,
				"Error refs definitions '%s'\n",
					def->name);
		    } else {
			if (ctxt->error != NULL)
			    ctxt->error(ctxt->userData,
				"Error refs definitions\n");
		    }
		    ctxt->nbErrors++;
		    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) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			    "Element %s is empty\n", node->name);
	    ctxt->nbErrors++;
	} 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) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			"xmlRelaxNGParse: notAllowed element is not empty\n");
	    ctxt->nbErrors++;
	}
    } else if (IS_RELAXNG(node, "grammar")) {
	xmlRelaxNGGrammarPtr grammar, old;
	xmlRelaxNGGrammarPtr oldparent;

#ifdef DEBUG_GRAMMAR
	xmlGenericError(xmlGenericErrorContext, "Found <grammar> pattern\n");
#endif

	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) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			"Use of parentRef without a parent grammar\n");
	    ctxt->nbErrors++;
	    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) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			    "parentRef has no name\n");
	    ctxt->nbErrors++;
	} else {
	    xmlRelaxNGNormExtSpace(def->name);
	    if (xmlValidateNCName(def->name, 0)) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"parentRef name '%s' is not an NCName\n",
				def->name);
		ctxt->nbErrors++;
	    }
	}
	if (node->children != NULL) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			    "parentRef is not empty\n");
	    ctxt->nbErrors++;
	}
	if (ctxt->parentgrammar->refs == NULL)
	    ctxt->parentgrammar->refs = xmlHashCreate(10);
	if (ctxt->parentgrammar->refs == NULL) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			    "Could not create references hash\n");
	    ctxt->nbErrors++;
	    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) {
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
			    "Internal error parentRef definitions '%s'\n",
				    def->name);
		    ctxt->nbErrors++;
		    def = NULL;
		} else {
		    def->nextHash = prev->nextHash;
		    prev->nextHash = def;
		}
	    }
	}
    } else if (IS_RELAXNG(node, "mixed")) {
	if (node->children == NULL) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
		    "Mixed is empty\n");
	    ctxt->nbErrors++;
	    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 {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
		"Unexpected node %s is not a pattern\n",
			node->name);
	ctxt->nbErrors++;
	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) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
		    "xmlRelaxNGParseattribute: attribute has no children\n");
	ctxt->nbErrors++;
	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:
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
		"attribute has invalid content\n");
		    ctxt->nbErrors++;
		    break;
		case XML_RELAXNG_NOOP:
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
		"RNG Internal error, noop found in attribute\n");
		    ctxt->nbErrors++;
		    break;
	    }
	}
	child = child->next;
    }
    if (child != NULL) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData, "attribute has multiple children\n");
	ctxt->nbErrors++;
    }
    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")) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
		"Expecting an except node\n");
	ctxt->nbErrors++;
	return(NULL);
    }
    if (node->next != NULL) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
		"exceptNameClass allows only a single except node\n");
	ctxt->nbErrors++;
    }
    if (node->children == NULL) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
		"except has no content\n");
	ctxt->nbErrors++;
	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 (ctxt->error != NULL) {
		if (node->parent != NULL)
		    ctxt->error(ctxt->userData,
			"Element %s name '%s' is not an NCName\n",
				node->parent->name, val);
		else
		    ctxt->error(ctxt->userData,
			"name '%s' is not an NCName\n",
				val);
	    }
	    ctxt->nbErrors++;
	}
	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"))) {
	    ctxt->error(ctxt->userData,
		"Attribute with namespace '%s' is not allowed\n",
			val);
	    ctxt->nbErrors++;
	}
	if ((ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE) &&
	    (val != NULL) &&
	    (val[0] == 0) &&
	    (xmlStrEqual(ret->name, BAD_CAST "xmlns"))) {
	    ctxt->error(ctxt->userData,
		"Attribute with QName 'xmlns' is not allowed\n",
			val);
	    ctxt->nbErrors++;
	}
    } 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) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
		    "nsName has no ns attribute\n");
	    ctxt->nbErrors++;
	}
	if ((ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE) &&
	    (ret->ns != NULL) &&
	    (xmlStrEqual(ret->ns, BAD_CAST "http://www.w3.org/2000/xmlns"))) {
	    ctxt->error(ctxt->userData,
		"Attribute with namespace '%s' is not allowed\n",
			ret->ns);
	    ctxt->nbErrors++;
	}
	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;

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

	if (node->children == NULL) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
		    "Element choice is empty\n");
	    ctxt->nbErrors++;
	} else {

	    child = node->children;
	    while (child != NULL) {
		tmp = xmlRelaxNGParseNameClass(ctxt, child, ret);
		if (tmp != NULL) {
		    if (last == NULL) {
			last = ret->nameClass = tmp;
		    } else {
			last->next = tmp;
			last = tmp;
		    }
		}
		child = child->next;
	    }
	}
    } else {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
    "expecting name, anyName, nsName or choice : got %s\n",
			node->name);
	ctxt->nbErrors++;
	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) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
			"xmlRelaxNGParseElement: element has no children\n");
	ctxt->nbErrors++;
	return(ret);
    } 
    cur = xmlRelaxNGParseNameClass(ctxt, child, ret);
    if (cur != NULL)
	child = child->next;

    if (child == NULL) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
			"xmlRelaxNGParseElement: element has no content\n");
	ctxt->nbErrors++;
	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:
		    /* HERE !!! */
		    cur->next = ret->attrs;
		    ret->attrs = cur;
		    break;
		case XML_RELAXNG_START:
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
		"RNG Internal error, start found in element\n");
		    ctxt->nbErrors++;
		    break;
		case XML_RELAXNG_PARAM:
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
		"RNG Internal error, param found in element\n");
		    ctxt->nbErrors++;
		    break;
		case XML_RELAXNG_EXCEPT:
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
		"RNG Internal error, except found in element\n");
		    ctxt->nbErrors++;
		    break;
		case XML_RELAXNG_NOOP:
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
		"RNG Internal error, noop found in element\n");
		    ctxt->nbErrors++;
		    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 (def == NULL) {
		def = last = cur;
	    } else {
		if ((group == 1) && (def->type == XML_RELAXNG_ELEMENT) &&
		    (def == last)) {
		    def = xmlRelaxNGNewDefine(ctxt, nodes);
		    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) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
			"start has no children\n");
	ctxt->nbErrors++;
	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) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData, "element empty is not empty\n");
	    ctxt->nbErrors++;
	}
    } 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) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			"element notAllowed is not empty\n");
	    ctxt->nbErrors++;
	}
    } 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) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
			"start more than one children\n");
	ctxt->nbErrors++;
	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) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
			"grammar has no children\n");
	ctxt->nbErrors++;
	return(-1);
    }
    while (nodes != NULL) {
	if (IS_RELAXNG(nodes, "start")) {
	    if (nodes->children == NULL) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
				"start has no children\n");
		ctxt->nbErrors++;
	    } 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 {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			"grammar has unexpected child %s\n", nodes->name);
	    ctxt->nbErrors++;
	    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(xmlRelaxNGDefinePtr ref,
		xmlRelaxNGParserCtxtPtr ctxt, const xmlChar *name) {
    xmlRelaxNGGrammarPtr grammar;
    xmlRelaxNGDefinePtr def, cur;

    grammar = ctxt->grammar;
    if (grammar == NULL) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
		    "Internal error: no grammar in CheckReference %s\n",
			name);
	ctxt->nbErrors++;
	return;
    }
    if (ref->content != NULL) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
	    "Internal error: reference has content in CheckReference %s\n",
			name);
	ctxt->nbErrors++;
	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 {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
		"Reference %s has no matching definition\n",
			    name);
	    ctxt->nbErrors++;
	}
    } else {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
	    "Reference %s has no matching definition\n",
			name);
	ctxt->nbErrors++;
    }
}

/**
 * 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(xmlRelaxNGDefinePtr define,
	xmlRelaxNGParserCtxtPtr ctxt, const xmlChar *name) {
    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) {
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
		    "Defines for %s use both 'choice' and 'interleave'\n",
		                    name);
		    ctxt->nbErrors++;
		}
	    } else if (xmlStrEqual(combine, BAD_CAST "interleave")) {
		if (choiceOrInterleave == -1)
		    choiceOrInterleave = 0;
		else if (choiceOrInterleave == 1) {
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
		    "Defines for %s use both 'choice' and 'interleave'\n",
		                    name);
		    ctxt->nbErrors++;
		}
	    } else {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
		    "Defines for %s use unknown combine value '%s''\n",
				name, combine);
		ctxt->nbErrors++;
	    }
	    xmlFree(combine);
	} else {
	    if (missing == 0)
		missing = 1;
	    else {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
		    "Some defines for %s needs the combine attribute\n",
				name);
		ctxt->nbErrors++;
	    }
	}

	cur = cur->nextHash;
    }
#ifdef DEBUG
    xmlGenericError(xmlGenericErrorContext,
		    "xmlRelaxNGCheckCombine(): merging %s defines: %d\n",
		    name, choiceOrInterleave);
#endif
    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) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
		    "Failed to create interleaves hash table\n");
	    ctxt->nbErrors++;
	} else {
	    char tmpname[32];

	    snprintf(tmpname, 32, "interleave%d", ctxt->nbInterleaves++);
	    if (xmlHashAddEntry(ctxt->interleaves, BAD_CAST tmpname, cur) < 0) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Failed to add %s to hash table\n", tmpname);
		ctxt->nbErrors++;
	    }
	}
    }
}

/**
 * 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;
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
		    "Internal error: start element not found\n");
	    ctxt->nbErrors++;
	} 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) {
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
		    "<start> use both 'choice' and 'interleave'\n");
		    ctxt->nbErrors++;
		}
	    } else if (xmlStrEqual(combine, BAD_CAST "interleave")) {
		if (choiceOrInterleave == -1)
		    choiceOrInterleave = 0;
		else if (choiceOrInterleave == 1) {
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
		    "<start> use both 'choice' and 'interleave'\n");
		    ctxt->nbErrors++;
		}
	    } else {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
		    "<start> uses unknown combine value '%s''\n", combine);
		ctxt->nbErrors++;
	    }
	    xmlFree(combine);
	} else {
	    if (missing == 0)
		missing = 1;
	    else {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
		    "Some <start> element miss the combine attribute\n");
		ctxt->nbErrors++;
	    }
	}

	cur = cur->next;
    }
#ifdef DEBUG
    xmlGenericError(xmlGenericErrorContext,
		    "xmlRelaxNGCombineStart(): merging <start>: %d\n",
		    choiceOrInterleave);
#endif
    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) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
		    "Failed to create interleaves hash table\n");
	    ctxt->nbErrors++;
	} else {
	    char tmpname[32];

	    snprintf(tmpname, 32, "interleave%d", ctxt->nbInterleaves++);
	    if (xmlHashAddEntry(ctxt->interleaves, BAD_CAST tmpname, cur) < 0) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Failed to add %s to hash table\n", tmpname);
		ctxt->nbErrors++;
	    }
	}
    }
}

/**
 * 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) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
		    "Detected a cycle in %s references\n", cur->name);
		ctxt->nbErrors++;
		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 possble 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 = flags;
    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)) {
	    if (flags & XML_RELAXNG_IN_LIST) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
		"Found forbidden pattern list//ref\n");
		ctxt->nbErrors++;
	    }
	    if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Found forbidden pattern data/except//ref\n");
		ctxt->nbErrors++;
	    }
	    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) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Found forbidden pattern data/except//element(ref)\n");
		ctxt->nbErrors++;
	    }
	    if (flags & XML_RELAXNG_IN_LIST) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
		"Found forbidden pattern list//element(ref)\n");
		ctxt->nbErrors++;
	    }
	    if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
		"Found forbidden pattern attribute//element(ref)\n");
		ctxt->nbErrors++;
	    }
	    if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Found forbidden pattern attribute//element(ref)\n");
		ctxt->nbErrors++;
	    }
	    /*
	     * 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) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Element %s attributes have a content type error\n",
			        cur->name);
		ctxt->nbErrors++;
	    }
	    ret = xmlRelaxNGCheckRules(ctxt, cur->content, nflags, cur->type);
	    if (ret == XML_RELAXNG_CONTENT_ERROR) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Element %s has a content type error\n",
			        cur->name);
		ctxt->nbErrors++;
	    } else {
		ret = XML_RELAXNG_CONTENT_COMPLEX;
	    }
	} else if (cur->type == XML_RELAXNG_ATTRIBUTE) {
	    if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Found forbidden pattern attribute//attribute\n");
		ctxt->nbErrors++;
	    }
	    if (flags & XML_RELAXNG_IN_LIST) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
		"Found forbidden pattern list//attribute\n");
		ctxt->nbErrors++;
	    }
	    if (flags & XML_RELAXNG_IN_OOMGROUP) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
		    "Found forbidden pattern oneOrMore//group//attribute\n");
		ctxt->nbErrors++;
	    }
	    if (flags & XML_RELAXNG_IN_OOMINTERLEAVE) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
		"Found forbidden pattern oneOrMore//interleave//attribute\n");
		ctxt->nbErrors++;
	    }
	    if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Found forbidden pattern data/except//attribute\n");
		ctxt->nbErrors++;
	    }
	    if (flags & XML_RELAXNG_IN_START) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Found forbidden pattern start//attribute\n");
		ctxt->nbErrors++;
	    }
	    if ((!(flags & XML_RELAXNG_IN_ONEORMORE)) && (cur->name == NULL)) {
		if (cur->ns == NULL) {
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
			"Found anyName attribute without oneOrMore ancestor\n");
		    ctxt->nbErrors++;
		} else {
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
			"Found nsName attribute without oneOrMore ancestor\n");
		    ctxt->nbErrors++;
		}
	    }
	    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) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Found forbidden pattern data/except//oneOrMore\n");
		ctxt->nbErrors++;
	    }
	    if (flags & XML_RELAXNG_IN_START) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Found forbidden pattern start//oneOrMore\n");
		ctxt->nbErrors++;
	    }
	    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) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
		"Found forbidden pattern list//list\n");
		ctxt->nbErrors++;
	    }
	    if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Found forbidden pattern data/except//list\n");
		ctxt->nbErrors++;
	    }
	    if (flags & XML_RELAXNG_IN_START) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Found forbidden pattern start//list\n");
		ctxt->nbErrors++;
	    }
	    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) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Found forbidden pattern data/except//group\n");
		ctxt->nbErrors++;
	    }
	    if (flags & XML_RELAXNG_IN_START) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Found forbidden pattern start//group\n");
		ctxt->nbErrors++;
	    }
	    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) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
		"Found forbidden pattern list//interleave\n");
		ctxt->nbErrors++;
	    }
	    if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Found forbidden pattern data/except//interleave\n");
		ctxt->nbErrors++;
	    }
	    if (flags & XML_RELAXNG_IN_START) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Found forbidden pattern start//interleave\n");
		ctxt->nbErrors++;
	    }
	    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) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Found forbidden pattern start//data\n");
		ctxt->nbErrors++;
	    }
	    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) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Found forbidden pattern start//value\n");
		ctxt->nbErrors++;
	    }
	    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) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
		"Found forbidden pattern list//text\n");
		ctxt->nbErrors++;
	    }
	    if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Found forbidden pattern data/except//text\n");
		ctxt->nbErrors++;
	    }
	    if (flags & XML_RELAXNG_IN_START) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Found forbidden pattern start//text\n");
		ctxt->nbErrors++;
	    }
	    ret = XML_RELAXNG_CONTENT_COMPLEX;
	} else if (cur->type == XML_RELAXNG_EMPTY) {
	    if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Found forbidden pattern data/except//empty\n");
		ctxt->nbErrors++;
	    }
	    if (flags & XML_RELAXNG_IN_START) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			"Found forbidden pattern start//empty\n");
		ctxt->nbErrors++;
	    }
	    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) {
	    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;

#ifdef DEBUG_GRAMMAR
    xmlGenericError(xmlGenericErrorContext, "Parsing a new grammar\n");
#endif

    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) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
	    "Failed to parse <grammar> content\n");
	ctxt->nbErrors++;
    } else if (ctxt->grammar->start == NULL) {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
	    "Element <grammar> has no <start>\n");
	ctxt->nbErrors++;
    }

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

    /*
     * link together defines and refs in this grammar
     */
    if (ret->refs != NULL) {
	xmlHashScan(ret->refs, (xmlHashScanner) 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 struture 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);
    } else {
	xmlRelaxNGGrammarPtr tmp, ret;

	schema->topgrammar = ret = xmlRelaxNGNewGrammar(ctxt);
	if (schema->topgrammar == NULL) {
	    return(schema);
	}
	/*
	 * 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);
	}
    }

#ifdef DEBUG
    if (schema == NULL)
        xmlGenericError(xmlGenericErrorContext,
                        "xmlRelaxNGParseDocument() failed\n");
#endif

    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) {
	xmlGenericError(xmlGenericErrorContext,
		"Failed to allocate new schama parser context for %s\n", URL);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));
    ret->URL = xmlStrdup((const xmlChar *)URL);
    ret->error = xmlGenericError;
    ret->userData = xmlGenericErrorContext;
    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) {
	xmlGenericError(xmlGenericErrorContext,
		"Failed to allocate new schama parser context\n");
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));
    ret->buffer = buffer;
    ret->size = size;
    ret->error = xmlGenericError;
    ret->userData = xmlGenericErrorContext;
    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) {
	xmlGenericError(xmlGenericErrorContext,
		"Failed to allocate new schama parser context\n");
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));
    ret->document = copy;
    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)
	xmlFreeDoc(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);
    }
    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(*cur)) cur++;
    if (cur == start) {
	do {
	    while ((*cur != 0) && (!IS_BLANK(*cur))) cur++;
	    if (*cur == 0)
		return;
	    start = cur;
	    while (IS_BLANK(*cur)) cur++;
	    if (*cur == 0) {
		*start = 0;
	        return;
	    }
	} while (1);
    } else {
	do {
	    while ((*cur != 0) && (!IS_BLANK(*cur))) 
		*start++ = *cur++;
	    if (*cur == 0) {
		*start = 0;
		return;
	    }
	    /* don't try to normalize the inner spaces */
	    while (IS_BLANK(*cur)) cur++;
		*start++ = *cur++;
	    if (*cur == 0) {
		*start = 0;
	        return;
	    }
	} while (1);
    }
}

/**
 * xmlRelaxNGCheckAttributes:
 * @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"))) {
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
				"Attribute %s is not allowed on %s\n",
				    cur->name, node->name);
		    ctxt->nbErrors++;
		}
	    } else if (xmlStrEqual(cur->name, BAD_CAST "type")) {
		if ((!xmlStrEqual(node->name, BAD_CAST "value")) &&
		    (!xmlStrEqual(node->name, BAD_CAST "data"))) {
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
				"Attribute %s is not allowed on %s\n",
				    cur->name, node->name);
		    ctxt->nbErrors++;
		}
	    } else if (xmlStrEqual(cur->name, BAD_CAST "href")) {
		if ((!xmlStrEqual(node->name, BAD_CAST "externalRef")) &&
		    (!xmlStrEqual(node->name, BAD_CAST "include"))) {
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
				"Attribute %s is not allowed on %s\n",
				    cur->name, node->name);
		    ctxt->nbErrors++;
		}
	    } else if (xmlStrEqual(cur->name, BAD_CAST "combine")) {
		if ((!xmlStrEqual(node->name, BAD_CAST "start")) &&
		    (!xmlStrEqual(node->name, BAD_CAST "define"))) {
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
				"Attribute %s is not allowed on %s\n",
				    cur->name, node->name);
		    ctxt->nbErrors++;
		}
	    } 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) {
			    if (ctxt->error != NULL)
				ctxt->error(ctxt->userData,
				"Attribute %s contains invalid URI %s\n",
					    cur->name, val);
			    ctxt->nbErrors++;
			} else {
			    if (uri->scheme == NULL) {
				if (ctxt->error != NULL)
				    ctxt->error(ctxt->userData,
				    "Attribute %s URI %s is not absolute\n",
						cur->name, val);
				ctxt->nbErrors++;
			    }
			    if (uri->fragment != NULL) {
				if (ctxt->error != NULL)
				    ctxt->error(ctxt->userData,
				    "Attribute %s URI %s has a fragment ID\n",
						cur->name, val);
				ctxt->nbErrors++;
			    }
			    xmlFreeURI(uri);
			}
		    }
		    xmlFree(val);
		}
	    } else if (!xmlStrEqual(cur->name, BAD_CAST "ns")) {
		if (ctxt->error != NULL)
		    ctxt->error(ctxt->userData,
			    "Unknown attribute %s on %s\n",
				cur->name, node->name);
		ctxt->nbErrors++;
	    }
	}
	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")))) {
		    if (ctxt->error != NULL)
			ctxt->error(ctxt->userData,
				"element %s doesn't allow foreign elements\n",
				    cur->parent->name);
		    ctxt->nbErrors++;
		}
		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;

		    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) {
			if (ctxt->error != NULL)
			    ctxt->error(ctxt->userData,
		    "xmlRelaxNGParse: externalRef has no href attribute\n");
			ctxt->nbErrors++;
			delete = cur;
			goto skip_children;
		    }
		    base = xmlNodeGetBase(cur->doc, cur);
		    URL = xmlBuildURI(href, base);
		    if (URL == NULL) {
			if (ctxt->error != NULL)
			    ctxt->error(ctxt->userData,
			"Failed to compute URL for externalRef %s\n", href);
			ctxt->nbErrors++;
			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) {
			if (ctxt->error != NULL)
			    ctxt->error(ctxt->userData,
				"Failed to load externalRef %s\n", URL);
			ctxt->nbErrors++;
			xmlFree(URL);
			delete = cur;
			goto skip_children;
		    }
		    if (ns != NULL)
			xmlFree(ns);
		    xmlFree(URL);
		    cur->_private = 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) {
			if (ctxt->error != NULL)
			    ctxt->error(ctxt->userData,
		    "xmlRelaxNGParse: include has no href attribute\n");
			ctxt->nbErrors++;
			delete = cur;
			goto skip_children;
		    }
		    base = xmlNodeGetBase(cur->doc, cur);
		    URL = xmlBuildURI(href, base);
		    if (URL == NULL) {
			if (ctxt->error != NULL)
			    ctxt->error(ctxt->userData,
			"Failed to compute URL for include %s\n", href);
			ctxt->nbErrors++;
			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) {
			if (ctxt->error != NULL)
			    ctxt->error(ctxt->userData,
				"Failed to load include %s\n", URL);
			ctxt->nbErrors++;
			xmlFree(URL);
			delete = cur;
			goto skip_children;
		    }
		    xmlFree(URL);
		    cur->_private = 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 = xmlNewNode(cur->ns, BAD_CAST "name");
			    if (node != NULL) {
				xmlAddPrevSibling(cur->children, node);
				text = xmlNewText(name);
				xmlAddChild(node, text);
				text = node;
			    }
			}
			if (text == NULL) {
			    if (ctxt->error != NULL)
				ctxt->error(ctxt->userData,
				"Failed to create a name %s element\n", name);
			    ctxt->nbErrors++;
			}
			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) {
				    if (ctxt->error != NULL)
					ctxt->error(ctxt->userData,
		    "xmlRelaxNGParse: no namespace for prefix %s\n", prefix);
				    ctxt->nbErrors++;
				} 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) {
			    if (ctxt->error != NULL)
				ctxt->error(ctxt->userData,
		    "Found nsName/except//nsName forbidden construct\n");
			    ctxt->nbErrors++;
			}
		    }
		} 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) {
			if (ctxt->error != NULL)
			    ctxt->error(ctxt->userData,
		"Found anyName/except//anyName forbidden construct\n");
			ctxt->nbErrors++;
		    } else if (ctxt->flags & XML_RELAXNG_IN_NSEXCEPT) {
			if (ctxt->error != NULL)
			    ctxt->error(ctxt->userData,
		"Found nsName/except//anyName forbidden construct\n");
			ctxt->nbErrors++;
		    }
		}
		/*
		 * Thisd 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);
		    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->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) {
        if (ctxt->error != NULL)
            ctxt->error(ctxt->userData, "xmlRelaxNGParse: %s is empty\n",
                        ctxt->URL);
	ctxt->nbErrors++;
        return (NULL);
    }
    xmlRelaxNGCleanupTree(ctxt, root);
    return(doc);
}

/**
 * xmlRelaxNGParse:
 * @ctxt:  a Relax-NG parser context
 *
 * parse a schema definition resource and build an internal
 * XML Shema struture which can be used to validate instances.
 * *WARNING* this interface is highly subject to change
 *
 * Returns the internal XML 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 = xmlParseFile((const char *) ctxt->URL);
	if (doc == NULL) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			    "xmlRelaxNGParse: could not load %s\n", ctxt->URL);
	    ctxt->nbErrors++;
	    return (NULL);
	}
    } else if (ctxt->buffer != NULL) {
	doc = xmlParseMemory(ctxt->buffer, ctxt->size);
	if (doc == NULL) {
	    if (ctxt->error != NULL)
		ctxt->error(ctxt->userData,
			    "xmlRelaxNGParse: could not parse schemas\n");
	    ctxt->nbErrors++;
	    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 {
	if (ctxt->error != NULL)
	    ctxt->error(ctxt->userData,
			"xmlRelaxNGParse: nothing to parse\n");
	ctxt->nbErrors++;
	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) {
        if (ctxt->error != NULL)
            ctxt->error(ctxt->userData, "xmlRelaxNGParse: %s is empty\n",
                        ctxt->URL);
	ctxt->nbErrors++;
	xmlFreeDoc(doc);
        return (NULL);
    }
    ret = xmlRelaxNGParseDocument(ctxt, root);
    if (ret == NULL) {
	xmlFreeDoc(doc);
	return(NULL);
    }

    /*
     * Check the ref/defines links
     */
    /*
     * try to preprocess interleaves
     */
    if (ctxt->interleaves != NULL) {
	xmlHashScan(ctxt->interleaves,
		(xmlHashScanner)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
 *
 * 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->userData = ctx;
}
/************************************************************************
 * 									*
 * 			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 (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 (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); 
    }
}

/************************************************************************
 * 									*
 * 		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;

#ifdef DEBUG_COMPILE
    xmlGenericError(xmlGenericErrorContext,
		    "Compiled callback for: '%s'\n", token);
#endif
    if (ctxt == NULL) {
	fprintf(stderr, "callback on %s missing context\n", token);
	if ((ctxt != NULL) && (ctxt->errNo == XML_RELAXNG_OK))
	    ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
	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 ((ctxt == NULL) || (define == NULL)) {
	fprintf(stderr, "callback on %s missing info\n", token);
	if ((ctxt != NULL) && (ctxt->errNo == XML_RELAXNG_OK))
	    ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
	return;
    } else 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);
}

/**
 * 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;

    if ((ctxt == NULL) || (regexp == NULL))
        return(-1);
    exec = xmlRegNewExecCtxt(regexp, 
                             xmlRelaxNGValidateCompiledCallback, ctxt);
    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);
    return(ret);
}

/************************************************************************
 * 									*
 * 		Progressive validation of when possible			*
 * 									*
 ************************************************************************/
static int xmlRelaxNGValidateAttributeList(xmlRelaxNGValidCtxtPtr ctxt, 
					   xmlRelaxNGDefinePtr defines);
static int xmlRelaxNGValidateElementEnd(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) {
	    VALID_ERR(XML_RELAXNG_ERR_MEMORY);
	    return(-1);
	}
    }
    if (ctxt->elemNr >= ctxt->elemMax) {
	ctxt->elemMax *= 2;
        ctxt->elemTab = (xmlRegExecCtxtPtr *) xmlRealloc(ctxt->elemTab,
	             ctxt->elemMax * sizeof(xmlRegExecCtxtPtr));
        if (ctxt->elemTab == NULL) {
	    VALID_ERR(XML_RELAXNG_ERR_MEMORY);
	    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 informations 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 = ctxt->pnode;
    int ret, oldflags;

#ifdef DEBUG_PROGRESSIVE
    xmlGenericError(xmlGenericErrorContext,
		    "Progressive callback for: '%s'\n", token);
#endif
    if (ctxt == NULL) {
	fprintf(stderr, "callback on %s missing context\n", token);
	return;
    }
    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 ((ctxt == NULL) || (define == NULL)) {
	fprintf(stderr, "callback on %s missing info\n", token);
	if ((ctxt != NULL) && (ctxt->errNo == XML_RELAXNG_OK))
	    ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
	ctxt->pstate = -1;
	return;
    } else 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
	 */
#ifdef DEBUG_PROGRESSIVE
	xmlGenericError(xmlGenericErrorContext,
		    "Element '%s' validation is not streamable\n", token);
#endif
	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);
	if (ret != 0) {
	    ctxt->pstate = -1;
	}
	xmlRelaxNGFreeValidState(ctxt, ctxt->state);
    } else if (ctxt->states != NULL) {
	int tmp = -1, i;

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

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

	    if (xmlRelaxNGValidateElementEnd(ctxt) == 0)
		tmp = 0;
	    xmlRelaxNGFreeValidState(ctxt, state);
	}
	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);

#ifdef DEBUG_PROGRESSIVE
    xmlGenericError(xmlGenericErrorContext, "PushElem %s\n", elem->name);
#endif
    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;
    }
#ifdef DEBUG_PROGRESSIVE
    if (ret < 0)
	xmlGenericError(xmlGenericErrorContext, "PushElem %s failed\n",
	                elem->name);
#endif
    return (ret);
}

/**
 * xmlRelaxNGValidatePushCData:
 * @ctxt:  the RelaxNG validation context
 * @data:  some character data read
 * @len:  the lenght 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);

#ifdef DEBUG_PROGRESSIVE
    xmlGenericError(xmlGenericErrorContext, "CDATA %s %d\n", data, len);
#endif

    while (*data != 0) {
        if (!IS_BLANK(*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 ");
#ifdef DEBUG_PROGRESSIVE
	xmlGenericError(xmlGenericErrorContext, "CDATA failed\n");
#endif

        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);
#ifdef DEBUG_PROGRESSIVE
    xmlGenericError(xmlGenericErrorContext, "PopElem %s\n", elem->name);
#endif
    /*
     * 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);
#ifdef DEBUG_PROGRESSIVE
    if (ret < 0)
	xmlGenericError(xmlGenericErrorContext, "PopElem %s failed\n",
	                elem->name);
#endif
    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);
#ifdef DEBUG_PROGRESSIVE
    xmlGenericError(xmlGenericErrorContext, "FullElem %s\n", elem->name);
#endif
    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, state);
    ctxt->state = NULL;
#ifdef DEBUG_PROGRESSIVE
    if (ret < 0)
	xmlGenericError(xmlGenericErrorContext, "FullElem %s failed\n",
	                elem->name);
#endif
    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_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) * sizeof(xmlChar));
    if (ret == NULL) {
	if (ctxt != NULL) {
	    VALID_ERR(XML_RELAXNG_ERR_MEMORY);
	} else {
	    xmlGenericError(xmlGenericErrorContext,
		"xmlRelaxNGNormalize: out of memory\n");
	}
        return(NULL);
    }
    p = ret;
    while (IS_BLANK(*str)) str++;
    while (*str != 0) {
	if (IS_BLANK(*str)) {
	    while (IS_BLANK(*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 dataype
 *
 * 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(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);
	    }
	    if (ret == 0)
		xmlRelaxNGNextValue(ctxt);
	    break;
	}
	case XML_RELAXNG_LIST: {
	    xmlRelaxNGDefinePtr list = define->content;
	    xmlChar *oldvalue, *oldend, *val, *cur;
#ifdef DEBUG_LIST
	    int nb_values = 0;
#endif

	    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(*cur)) {
		    *cur = 0;
		    cur++;
#ifdef DEBUG_LIST
		    nb_values++;
#endif
		    while (IS_BLANK(*cur))
			*cur++ = 0;
		} else
		    cur++;
	    }
#ifdef DEBUG_LIST
	    xmlGenericError(xmlGenericErrorContext,
		    "list value: '%s' found %d items\n", oldvalue, nb_values);
	    nb_values = 0;
#endif 
	    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) {
#ifdef DEBUG_LIST
		    xmlGenericError(xmlGenericErrorContext,
			"Failed to validate value: '%s' with %d rule\n",
		                    ctxt->state->value, nb_values);
#endif
		    break;
		}
#ifdef DEBUG_LIST
		nb_values++;
#endif
		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;
	    }
	    /* no break on purpose */
        case XML_RELAXNG_ZEROORMORE: {
            xmlChar *cur, *temp;

	    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 (ret != 0) {
		if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
		    xmlRelaxNGDumpValidError(ctxt);
	    } else {
		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:
	    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 {
	TODO
    }
    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;
	}
#ifdef DEBUG
	xmlGenericError(xmlGenericErrorContext,
                    "xmlRelaxNGValidateAttribute(%s): %d\n", define->name, ret);
#endif
    } 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;
	}
#ifdef DEBUG
	if (define->ns != NULL) {
	    xmlGenericError(xmlGenericErrorContext,
			"xmlRelaxNGValidateAttribute(nsName ns = %s): %d\n",
			    define->ns, ret);
	} else {
	    xmlGenericError(xmlGenericErrorContext,
			"xmlRelaxNGValidateAttribute(anyName): %d\n",
			    ret);
	}
#endif
    }
    
    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_TEXT)) {
	    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, left;
    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;
	left = 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) {
	VALID_ERR(XML_RELAXNG_ERR_MEMORY);
	return(-1);
    }
    memset(list, 0, nbgroups * sizeof(xmlNodePtr));
    lasts = (xmlNodePtr *) xmlMalloc(nbgroups * sizeof(xmlNodePtr));
    if (lasts == NULL) {
	VALID_ERR(XML_RELAXNG_ERR_MEMORY);
	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 = ((long) 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);
	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) {
		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;

	    for (j = 0;j < ctxt->states->nbState;j++) {
		cur = ctxt->states->tabState[j]->seq;
		cur = xmlRelaxNGSkipIgnored(ctxt, cur);
		if (cur == NULL) {
		    found = 1;
		    break;
		}
	    }
	    if (ctxt->states->nbState > 0) {
		xmlRelaxNGFreeValidState(ctxt,oldstate);
		oldstate = ctxt->states->tabState[ctxt->states->nbState - 1];
	    }
	    for (j = 0;j < ctxt->states->nbState - 1;j++) {
		xmlRelaxNGFreeValidState(ctxt,ctxt->states->tabState[j]);
	    }
	    xmlRelaxNGFreeStates(ctxt, ctxt->states);
	    ctxt->states = NULL;
	    if (found == 0) {
		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);
}

/**
 * xmlRelaxNGValidateElementEnd:
 * @ctxt:  a Relax-NG validation context
 *
 * 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 ret = 0, i;
    xmlRelaxNGValidStatePtr state;

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

/**
 * 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;
    }
#ifdef DEBUG
    for (i = 0; i < ctxt->depth; i++)
        xmlGenericError(xmlGenericErrorContext, " ");
    xmlGenericError(xmlGenericErrorContext,
                    "Start validating %s ", xmlRelaxNGDefName(define));
    if (define->name != NULL)
        xmlGenericError(xmlGenericErrorContext, "%s ", define->name);
    if ((node != NULL) && (node->name != NULL))
        xmlGenericError(xmlGenericErrorContext, "on %s\n", node->name);
    else
        xmlGenericError(xmlGenericErrorContext, "\n");
#endif
    ctxt->depth++;
    switch (define->type) {
        case XML_RELAXNG_EMPTY:
            node = xmlRelaxNGSkipIgnored(ctxt, node);
            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->_private == 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);

#ifdef DEBUG_COMPILE
		xmlGenericError(xmlGenericErrorContext,
			"Validating content of '%s' : %d\n", define->name, tmp);
#endif
                if (tmp != 0)
		    ret = -1;

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

                    ctxt->flags |= FLAGS_IGNORABLE;

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

                        if (xmlRelaxNGValidateElementEnd(ctxt) == 0)
                            tmp = 0;
                        xmlRelaxNGFreeValidState(ctxt, state);
                    }
                    xmlRelaxNGFreeStates(ctxt, ctxt->states);
                    ctxt->flags = oldflags;
                    ctxt->states = NULL;
                    if ((ret == 0) && (tmp == -1))
                        ret = -1;
                } else {
                    state = ctxt->state;
		    ctxt->state->seq = nseq;
                    if (ret == 0)
                        ret = xmlRelaxNGValidateElementEnd(ctxt);
                    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;

                    ctxt->flags |= FLAGS_IGNORABLE;

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

                        if (xmlRelaxNGValidateElementEnd(ctxt) == 0)
                            tmp = 0;
                        xmlRelaxNGFreeValidState(ctxt, state);
                    }
                    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);
                    xmlRelaxNGFreeValidState(ctxt, state);
                }
            }
            if (ret == 0) {
                node->_private = 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;
                } else {
                    ret = -2;
                }
            } else {
                if (ctxt->errNr > errNr)
                    xmlRelaxNGPopErrors(ctxt, errNr);
            }

#ifdef DEBUG
            xmlGenericError(xmlGenericErrorContext,
                            "xmlRelaxNGValidateDefinition(): validated %s : %d",
                            node->name, ret);
            if (oldstate == NULL)
                xmlGenericError(xmlGenericErrorContext, ": no state\n");
            else if (oldstate->seq == NULL)
                xmlGenericError(xmlGenericErrorContext, ": done\n");
            else if (oldstate->seq->type == XML_ELEMENT_NODE)
                xmlGenericError(xmlGenericErrorContext, ": next elem %s\n",
                                oldstate->seq->name);
            else
                xmlGenericError(xmlGenericErrorContext, ": next %s %d\n",
                                oldstate->seq->name, oldstate->seq->type);
#endif
            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);
            /* no break on purpose */
        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->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 (ctxt->errNr > errNr)
                    xmlRelaxNGPopErrors(ctxt, errNr);
                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)) {
                    xmlHashTablePtr triage =
                        (xmlHashTablePtr) define->data;

                    /*
                     * Something we can optimize cleanly there is only one
                     * possble branch out !
                     */
                    if (node == NULL) {
                        ret = -1;
                        break;
                    }
                    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;
                        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) {
                        VALID_ERR(XML_RELAXNG_ERR_MEMORY);
                        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) {
                        VALID_ERR(XML_RELAXNG_ERR_MEMORY);
                        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) {
                        VALID_ERR(XML_RELAXNG_ERR_MEMORY);
                        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--;
#ifdef DEBUG
    for (i = 0; i < ctxt->depth; i++)
        xmlGenericError(xmlGenericErrorContext, " ");
    xmlGenericError(xmlGenericErrorContext,
                    "Validating %s ", xmlRelaxNGDefName(define));
    if (define->name != NULL)
        xmlGenericError(xmlGenericErrorContext, "%s ", define->name);
    if (ret == 0)
        xmlGenericError(xmlGenericErrorContext, "suceeded\n");
    else
        xmlGenericError(xmlGenericErrorContext, "failed\n");
#endif
    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 DEBUG
    else if (ctxt->errNr != 0) {
	ctxt->error(ctxt->userData, "%d Extra error messages left on stack !\n",
		    ctxt->errNr);
	xmlRelaxNGDumpValidError(ctxt);
    }
#endif
    if (ctxt->idref == 1) {
	xmlValidCtxt vctxt;

	memset(&vctxt, 0, sizeof(xmlValidCtxt));
	vctxt.valid = 1;
	vctxt.error = ctxt->error;
	vctxt.warning = ctxt->warning;
	vctxt.userData = ctxt->userData;

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

    return(ret);
}

/************************************************************************
 * 									*
 * 			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) {
	xmlGenericError(xmlGenericErrorContext,
		"Failed to allocate new schema validation context\n");
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlRelaxNGValidCtxt));
    ret->schema = schema;
    ret->error = xmlGenericError;
    ret->userData = xmlGenericErrorContext;
    ret->errNr = 0;
    ret->errMax = 0;
    ret->err = NULL;
    ret->errTab = 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
 *
 * Set the error and warning callback informations
 */
void
xmlRelaxNGSetValidErrors(xmlRelaxNGValidCtxtPtr ctxt,
	xmlRelaxNGValidityErrorFunc err,
	xmlRelaxNGValidityWarningFunc warn, void *ctx) {
    if (ctxt == NULL)
	return;
    ctxt->error = err;
    ctxt->warning = warn;
    ctxt->userData = ctx;
}

/**
 * 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);
    /*
     * TODO: build error codes
     */
    if (ret == -1)
	return(1);
    return(ret);
}

#endif /* LIBXML_SCHEMAS_ENABLED */

