Release 0.2, 80% rewrite, nothing left intact ... Daniel
diff --git a/ChangeLog b/ChangeLog
index 811b39c..d31661e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Wed Aug 12 23:12:58 EDT 1998  Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* New release 0.2, removed the old xml_* files so that it's
+	    coherent with the other CVS base (W3C), far better conformance
+	    to standard, new namespaces, decent entities support, beginning
+	    of a SAX-like interface. Nearly nothing left intact, even the
+	    test examples ...
+
 1998-07-30  Christopher Blizzard  <blizzard@appliedtheory.com>
 
 	* .cvsignore: Add .deps dir
diff --git a/Makefile.am b/Makefile.am
index 02a6bd8..bbc78de 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,14 +5,18 @@
 lib_LTLIBRARIES = libxml.la
 
 libxml_la_SOURCES = \
-		xml_entities.c \
-		xml_parser.c \
-		xml_tree.c
+		SAX.c \
+		entities.c \
+		error.c \
+		parser.c \
+		tester.c \
+		tree.c
+
 
 include_HEADERS = \
-		xml_entities.h \
-		xml_parser.h \
-		xml_tree.h
+		entities.h \
+		parser.h \
+		tree.h
 
 DEPS = $(top_builddir)/libxml.la
 LDADDS = $(top_builddir)/libxml.la @Z_LIBS@
diff --git a/Makefile.win b/Makefile.win
new file mode 100644
index 0000000..0d36057
--- /dev/null
+++ b/Makefile.win
@@ -0,0 +1,34 @@
+# This is a makefile for win32 systems (VC 5.0).
+# Christopher Blizzard
+# http://odin.appliedtheory.com/
+
+CC = cl
+CFLAGS = /c /GB /Gi /nologo /I. /DWIN32 /MT /Zi
+
+LD = link
+LDFLAGS = /DEBUG /NODEFAULTLIB:libc
+
+AR = lib
+
+all: xml.lib
+
+test: tester.exe
+
+SHARED_OBJS = entities.obj parser.obj tree.obj SAX.obj
+
+xml.lib: $(SHARED_OBJS)
+	$(AR) /out:xml.lib $(SHARED_OBJS)
+
+tester.obj: $(SHARED_OBJS)
+	$(CC) $(CFLAGS) tester.c /out:tester.obj
+
+tester.exe: tester.obj xml.lib
+	$(LD) $(LDFLAGS) /out:tester.exe tester.obj xml.lib
+
+clean:
+	-del /f $(SHARED_OBJS) tester.obj
+	-del /f tester.exe
+	-del /f xml.lib
+	-del /f *.pdb
+	-del /f *.idb
+	-del /f *.ilk
diff --git a/SAX.c b/SAX.c
new file mode 100644
index 0000000..17a8277
--- /dev/null
+++ b/SAX.c
@@ -0,0 +1,223 @@
+/*
+ * SAX.c : Default SAX handler to build a tree.
+ */
+
+#include <stdio.h>
+#include <malloc.h>
+#include "tree.h"
+#include "parser.h"
+#include "error.h"
+
+/* #define DEBUG_SAX */
+
+/*
+ * Return the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
+ */
+const CHAR *getPublicId(xmlParserCtxtPtr ctxt) {
+    return(NULL);
+}
+
+/*
+ * Return the system ID, basically URI or filename e.g.
+ *  http://www.sgmlsource.com/dtds/memo.dtd
+ */
+const CHAR *getSystemId(xmlParserCtxtPtr ctxt) {
+    return(ctxt->input->filename); 
+}
+
+/*
+ * Return the line number of the current parsing point.
+ */
+int getLineNumber(xmlParserCtxtPtr ctxt) {
+    return(ctxt->input->line);
+}
+/*
+ * Return the column number of the current parsing point.
+ */
+int getColumnNumber(xmlParserCtxtPtr ctxt) {
+    return(ctxt->input->col);
+}
+
+/*
+ * The default SAX Locator.
+ */
+
+xmlSAXLocator xmlDefaultSAXLocator = {
+    getPublicId, getSystemId, getLineNumber, getColumnNumber
+};
+
+/*
+ * Special entity resolver, better left to the parser, it has
+ * more context than the application layer.
+ */
+xmlParserInputPtr resolveEntity(xmlParserCtxtPtr ctxt, 
+			    const CHAR *publicId, const CHAR *systemId) {
+
+#ifdef DEBUG_SAX
+    fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
+#endif
+    return(NULL);
+}
+
+/*
+ * What to do when a notation declaration has been parsed.
+ * TODO Not handled currently.
+ */
+void notationDecl(xmlParserCtxtPtr ctxt, const CHAR *name,
+		  const CHAR *publicId, const CHAR *systemId) {
+#ifdef DEBUG_SAX
+    fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
+#endif
+}
+
+/*
+ * What to do when an unparsed entity declaration is parsed
+ * TODO Create an Entity node.
+ */
+void unparsedEntityDecl(xmlParserCtxtPtr ctxt, const CHAR *name,
+			const CHAR *publicId, const CHAR *systemId,
+			const CHAR *notationName) {
+#ifdef DEBUG_SAX
+    fprintf(stderr, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
+            name, publicId, systemId, notationName);
+#endif
+}
+
+/*
+ * Receive the document locator at startup, actually xmlDefaultSAXLocator
+ * Everything is available on the context, so this is useless in our case.
+ */
+void setDocumentLocator(xmlParserCtxtPtr ctxt, xmlSAXLocatorPtr loc) {
+#ifdef DEBUG_SAX
+    fprintf(stderr, "SAX.setDocumentLocator()\n");
+#endif
+}
+
+/*
+ * called when the document start being processed.
+ */
+void startDocument(xmlParserCtxtPtr ctxt) {
+#ifdef DEBUG_SAX
+    fprintf(stderr, "SAX.startDocument()\n");
+#endif
+}
+
+/*
+ * called when the document end has been detected.
+ */
+void endDocument(xmlParserCtxtPtr ctxt) {
+#ifdef DEBUG_SAX
+    fprintf(stderr, "SAX.endDocument()\n");
+#endif
+}
+
+/*
+ * called when an opening tag has been processed.
+ * TODO We currently have a small pblm with the arguments ...
+ */
+void startElement(xmlParserCtxtPtr ctxt, const CHAR *name) {
+    xmlNodePtr parent;
+
+#ifdef DEBUG_SAX
+    fprintf(stderr, "SAX.startElement(%s)\n", name);
+#endif
+    if (ctxt->nodeNr < 2) return;
+    parent = ctxt->nodeTab[ctxt->nodeNr - 2];
+    if (parent != NULL)
+	xmlAddChild(parent, ctxt->node);
+    
+}
+
+/*
+ * called when the end of an element has been detected.
+ */
+void endElement(xmlParserCtxtPtr ctxt, const CHAR *name) {
+#ifdef DEBUG_SAX
+    fprintf(stderr, "SAX.endElement(%s)\n", name);
+#endif
+}
+
+/*
+ * receiving some chars from the parser.
+ * Question: how much at a time ???
+ */
+void characters(xmlParserCtxtPtr ctxt, const CHAR *ch,
+                       int start, int len) {
+    xmlNodePtr lastChild;
+
+#ifdef DEBUG_SAX
+    fprintf(stderr, "SAX.characters(%.30s, %d, %d)\n", ch, start, len);
+#endif
+    /*
+     * Handle the data if any. If there is no child
+     * add it as content, otherwise if the last child is text,
+     * concatenate it, else create a new node of type text.
+     */
+
+    lastChild = xmlGetLastChild(ctxt->node);
+    if (lastChild == NULL)
+	xmlNodeAddContentLen(ctxt->node, &ch[start], len);
+    else {
+	if (xmlNodeIsText(lastChild))
+	    xmlTextConcat(lastChild, &ch[start], len);
+	else {
+	    lastChild = xmlNewTextLen(&ch[start], len);
+	    xmlAddChild(ctxt->node, lastChild);
+	}
+    }
+}
+
+/*
+ * receiving some ignorable whitespaces from the parser.
+ * Question: how much at a time ???
+ */
+void ignorableWhitespace(xmlParserCtxtPtr ctxt, const CHAR *ch,
+                         int start, int len) {
+#ifdef DEBUG_SAX
+    fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d, %d)\n", ch, start, len);
+#endif
+}
+
+/*
+ * A processing instruction has beem parsed.
+ */
+void processingInstruction(xmlParserCtxtPtr ctxt, const CHAR *target,
+			   const CHAR *data) {
+#ifdef DEBUG_SAX
+    fprintf(stderr, "SAX.processingInstruction(%s, %s)\n", target, data);
+#endif
+}
+
+xmlSAXHandler xmlDefaultSAXHandler = {
+    resolveEntity,
+    notationDecl,
+    unparsedEntityDecl,
+    setDocumentLocator,
+    startDocument,
+    endDocument,
+    startElement,
+    endElement,
+    characters,
+    ignorableWhitespace,
+    processingInstruction,
+    xmlParserWarning,
+    xmlParserError,
+    xmlParserError,
+};
+
+void xmlDefaultSAXHandlerInit(void) {
+    xmlDefaultSAXHandler.resolveEntity = resolveEntity;
+    xmlDefaultSAXHandler.notationDecl = notationDecl;
+    xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl;
+    xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
+    xmlDefaultSAXHandler.startDocument = startDocument;
+    xmlDefaultSAXHandler.endDocument = endDocument;
+    xmlDefaultSAXHandler.startElement = startElement;
+    xmlDefaultSAXHandler.endElement = endElement;
+    xmlDefaultSAXHandler.characters = characters;
+    xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
+    xmlDefaultSAXHandler.processingInstruction = processingInstruction;
+    xmlDefaultSAXHandler.warning = xmlParserWarning;
+    xmlDefaultSAXHandler.error = xmlParserError;
+    xmlDefaultSAXHandler.fatalError = xmlParserError;
+}
diff --git a/TODO b/TODO
index 8fd623c..d8218bc 100644
--- a/TODO
+++ b/TODO
@@ -1,15 +1,11 @@
 
            TODO for the XML parser:
 
-- Support for UTF-8 encoding
-- progressive parsing. Currently the parser uses a single
-  string containing the full document. The good point is
-  that there is no context associated with the parser, the
-  full state is in the stack. The bad point is that such a
-  recursive design is hard to make progressive ...
-- Better error handling, use a dedicated, overridable error
-  handling function.
-- Keep track of line numbers for better error reporting.
+- Support for UTF-8 and UTF-16 encoding (Urgent !!!).
+- progressive parsing. The entity support is a first step toward
+  asbtraction of an input stream. A large part of the context is still
+  located on the stack, moving to a state machine and putting everyting
+  in the parsing context should provide an adequate solution.
 - DOM support, instead of using a proprietary in memory
   format for the document representation, the parser should
   call a DOM API to actually build the resulting document.
@@ -17,14 +13,17 @@
   representation of the document. Even better using RPC's
   the parser can actually build the document in another
   program.
-- finish the support for Entities.
 - Support for Comments (bad, should be in ASAP, they are parsed
-  but not stored).
-- Support for PI.
-- Support for CDATA.
+  but not stored), should be configurable.
+- Improve the support of entities on save (+SAX).
 
 Done:
 - C++ support : John Ehresman <jehresma@dsg.harvard.edu>
 - Updated code to follow more recent specs, added compatibility flag
+- Better error handling, use a dedicated, overridable error
+  handling function.
+- Support for CDATA.
+- Keep track of line numbers for better error reporting.
+- Support for PI (SAX one).
 
 $Id$
diff --git a/autogen.sh b/autogen.sh
index 0119b5c..69f0382 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -5,7 +5,7 @@
 
 (autoconf --version) < /dev/null > /dev/null 2>&1 || {
 	echo
-	echo "You must have autoconf installed to compile GLIB."
+	echo "You must have autoconf installed to compile gnome-xml."
 	echo "Download the appropriate package for your distribution,"
 	echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
 	DIE=1
@@ -13,7 +13,7 @@
 
 (libtool --version) < /dev/null > /dev/null 2>&1 || {
 	echo
-	echo "You must have libtool installed to compile GLIB."
+	echo "You must have libtool installed to compile gnome-xml."
 	echo "Get ftp://alpha.gnu.org/gnu/libtool-1.0h.tar.gz"
 	echo "(or a newer version if it is available)"
 	DIE=1
@@ -21,7 +21,7 @@
 
 (automake --version) < /dev/null > /dev/null 2>&1 || {
 	echo
-	echo "You must have automake installed to compile GLIB."
+	echo "You must have automake installed to compile gnome-xml."
 	echo "Get ftp://ftp.cygnus.com/pub/home/tromey/automake-1.2d.tar.gz"
 	echo "(or a newer version if it is available)"
 	DIE=1
@@ -31,8 +31,8 @@
 	exit 1
 fi
 
-test -f xml_entities.h || {
-	echo "You must run this script in the top-level GLIB directory"
+test -f entities.h || {
+	echo "You must run this script in the top-level gnome-xml directory"
 	exit 1
 }
 
diff --git a/config.h b/config.h
new file mode 100644
index 0000000..758ca6d
--- /dev/null
+++ b/config.h
@@ -0,0 +1,62 @@
+/* config.h.  Generated automatically by configure.  */
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define if you have the strftime function.  */
+#define HAVE_STRFTIME 1
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* Define if you have the snprintf function.  */
+#define HAVE_SNPRINTF 1
+
+/* Define if you have the strdup function.  */
+#define HAVE_STRDUP 1
+
+/* Define if you have the strerror function.  */
+#define HAVE_STRERROR 1
+
+/* Define if you have the strndup function.  */
+#define HAVE_STRNDUP 1
+
+/* Define if you have the <ctype.h> header file.  */
+#define HAVE_CTYPE_H 1
+
+/* Define if you have the <dirent.h> header file.  */
+#define HAVE_DIRENT_H 1
+
+/* Define if you have the <errno.h> header file.  */
+#define HAVE_ERRNO_H 1
+
+/* Define if you have the <fcntl.h> header file.  */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <malloc.h> header file.  */
+#define HAVE_MALLOC_H 1
+
+/* Define if you have the <ndir.h> header file.  */
+/* #undef HAVE_NDIR_H */
+
+/* Define if you have the <stdarg.h> header file.  */
+#define HAVE_STDARG_H 1
+
+/* Define if you have the <sys/dir.h> header file.  */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define if you have the <sys/ndir.h> header file.  */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define if you have the <sys/stat.h> header file.  */
+#define HAVE_SYS_STAT_H 1
+
+/* Define if you have the <sys/types.h> header file.  */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define if you have the <time.h> header file.  */
+#define HAVE_TIME_H 1
+
+/* Define if you have the <unistd.h> header file.  */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the <zlib.h> header file.  */
+#define HAVE_ZLIB_H 1
diff --git a/configure.in b/configure.in
index 285c00c..4048bb9 100644
--- a/configure.in
+++ b/configure.in
@@ -1,8 +1,8 @@
 dnl Process this file with autoconf to produce a configure script.
 AC_PREREQ(2.2)
-AC_INIT(xml_entities.h)
+AC_INIT(entities.h)
 AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(libxml, 0.10)
+AM_INIT_AUTOMAKE(libxml, 0.20)
 
 dnl Checks for programs.
 AC_PROG_CC
diff --git a/entities.c b/entities.c
new file mode 100644
index 0000000..47b7cfa
--- /dev/null
+++ b/entities.c
@@ -0,0 +1,426 @@
+/*
+ * entities.c : implementation for the XML entities handking
+ *
+ * See Copyright for the status of this software.
+ *
+ * $Id$
+ */
+
+#include <stdio.h>
+#include <malloc.h>
+#include <string.h>
+#include "entities.h"
+
+/*
+ * The XML predefined entities.
+ */
+
+struct xmlPredefinedEntityValue {
+    const char *name;
+    const char *value;
+};
+struct xmlPredefinedEntityValue xmlPredefinedEntityValues[] = {
+    { "lt", "<" },
+    { "gt", ">" },
+    { "apos", "'" },
+    { "quot", "\"" },
+    { "amp", "&" }
+};
+
+xmlEntitiesTablePtr xmlPredefinedEntities = NULL;
+
+/*
+ * A buffer used for converting entities to their equivalent and back.
+ */
+static int buffer_size = 0;
+static CHAR *buffer = NULL;
+
+void growBuffer(void) {
+    buffer_size *= 2;
+    buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
+    if (buffer == NULL) {
+	perror("realloc failed");
+	exit(1);
+    }
+}
+
+/*
+ * xmlFreeEntity : clean-up an entity record.
+ */
+
+void xmlFreeEntity(xmlEntityPtr entity) {
+    if (entity == NULL) return;
+
+    if (entity->name != NULL)
+	free((char *) entity->name);
+    if (entity->ExternalID != NULL)
+        free((char *) entity->ExternalID);
+    if (entity->SystemID != NULL)
+        free((char *) entity->SystemID);
+    if (entity->content != NULL)
+        free((char *) entity->content);
+    memset(entity, -1, sizeof(xmlEntity));
+}
+
+/*
+ * xmlAddDocEntity : register a new entity for an entities table.
+ *
+ * TODO !!! We should check here that the combination of type
+ *          ExternalID and SystemID is valid.
+ */
+static void xmlAddEntity(xmlEntitiesTablePtr table, const CHAR *name, int type,
+              const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
+    int i;
+    xmlEntityPtr cur;
+    int len;
+
+    for (i = 0;i < table->nb_entities;i++) {
+        cur = &table->table[i];
+	if (!xmlStrcmp(cur->name, name)) {
+	    /*
+	     * The entity is already defined in this Dtd, the spec says to NOT
+	     * override it ... Is it worth a Warning ??? !!!
+	     */
+	    return;
+	}
+    }
+    if (table->nb_entities >= table->max_entities) {
+        /*
+	 * need more elements.
+	 */
+	table->max_entities *= 2;
+	table->table = (xmlEntityPtr) 
+	    realloc(table->table, table->max_entities * sizeof(xmlEntity));
+	if (table->table) {
+	    perror("realloc failed");
+	    exit(1);
+	}
+    }
+    cur = &table->table[table->nb_entities];
+    cur->name = xmlStrdup(name);
+    for (len = 0;name[0] != 0;name++)len++;
+    cur->len = len;
+    cur->type = type;
+    if (ExternalID != NULL)
+	cur->ExternalID = xmlStrdup(ExternalID);
+    else
+        cur->ExternalID = NULL;
+    if (SystemID != NULL)
+	cur->SystemID = xmlStrdup(SystemID);
+    else
+        cur->SystemID = NULL;
+    if (content != NULL)
+	cur->content = xmlStrdup(content);
+    else
+        cur->content = NULL;
+    table->nb_entities++;
+}
+
+/*
+ * Set up xmlPredefinedEntities from xmlPredefinedEntityValues.
+ */
+void xmlInitializePredefinedEntities(void) {
+    int i;
+    CHAR name[50];
+    CHAR value[50];
+    const char *in;
+    CHAR *out;
+
+    if (xmlPredefinedEntities != NULL) return;
+
+    xmlPredefinedEntities = xmlCreateEntitiesTable();
+    for (i = 0;i < sizeof(xmlPredefinedEntityValues) / 
+                   sizeof(xmlPredefinedEntityValues[0]);i++) {
+        in = xmlPredefinedEntityValues[i].name;
+	out = &name[0];
+	for (;(*out++ = (CHAR) *in);)in++;
+        in = xmlPredefinedEntityValues[i].value;
+	out = &value[0];
+	for (;(*out++ = (CHAR) *in);)in++;
+        xmlAddEntity(xmlPredefinedEntities, (const CHAR *) &name[0],
+	             XML_INTERNAL_GENERAL_ENTITY, NULL, NULL,
+		     &value[0]);
+    }
+}
+
+
+/*
+ * xmlAddDtdEntity : register a new entity for this DTD.
+ */
+void xmlAddDtdEntity(xmlDocPtr doc, const CHAR *name, int type,
+              const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
+    xmlEntitiesTablePtr table;
+
+    if (doc->dtd == NULL) {
+        fprintf(stderr, "xmlAddDtdEntity: document without Dtd !\n");
+	return;
+    }
+    table = (xmlEntitiesTablePtr) doc->dtd->entities;
+    if (table == NULL) {
+        table = xmlCreateEntitiesTable();
+	doc->dtd->entities = table;
+    }
+    xmlAddEntity(table, name, type, ExternalID, SystemID, content);
+}
+
+/*
+ * xmlAddDocEntity : register a new entity for this document.
+ */
+void xmlAddDocEntity(xmlDocPtr doc, const CHAR *name, int type,
+              const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
+    xmlEntitiesTablePtr table;
+
+    table = (xmlEntitiesTablePtr) doc->entities;
+    if (table == NULL) {
+        table = xmlCreateEntitiesTable();
+	doc->entities = table;
+    }
+    xmlAddEntity(doc->entities, name, type, ExternalID, SystemID, content);
+}
+
+/*
+ * xmlGetDtdEntity : do an entity lookup in the Dtd entity hash table and
+ *       returns the corrsponding entity, if found, NULL otherwise.
+ */
+xmlEntityPtr xmlGetDtdEntity(xmlDocPtr doc, const CHAR *name) {
+    int i;
+    xmlEntityPtr cur;
+    xmlEntitiesTablePtr table;
+
+    if ((doc->dtd != NULL) && (doc->dtd->entities != NULL)) {
+	table = (xmlEntitiesTablePtr) doc->dtd->entities;
+	for (i = 0;i < table->nb_entities;i++) {
+	    cur = &table->table[i];
+	    if (!xmlStrcmp(cur->name, name)) return(cur);
+	}
+    }
+    return(NULL);
+}
+
+/*
+ * xmlGetDocEntity : do an entity lookup in the document entity hash table and
+ *       returns the corrsponding entity, otherwise a lookup is done
+ *       in the predefined entities too.
+ */
+xmlEntityPtr xmlGetDocEntity(xmlDocPtr doc, const CHAR *name) {
+    int i;
+    xmlEntityPtr cur;
+    xmlEntitiesTablePtr table;
+
+    if (doc->entities != NULL) {
+	table = (xmlEntitiesTablePtr) doc->entities;
+	for (i = 0;i < table->nb_entities;i++) {
+	    cur = &table->table[i];
+	    if (!xmlStrcmp(cur->name, name)) return(cur);
+	}
+    }
+    if (xmlPredefinedEntities == NULL)
+        xmlInitializePredefinedEntities();
+    table = xmlPredefinedEntities;
+    for (i = 0;i < table->nb_entities;i++) {
+	cur = &table->table[i];
+	if (!xmlStrcmp(cur->name, name)) return(cur);
+    }
+
+    return(NULL);
+}
+
+/*
+ * xmlEncodeEntities : do a global encoding of a string, replacing the
+ *                     basic content with their entities form.
+ * TODO !!!! rewite !!!
+ */
+CHAR *xmlEncodeEntities(xmlDocPtr doc, const CHAR *input) {
+    const CHAR *cur = input;
+    CHAR *out = buffer;
+
+    if (buffer == NULL) {
+        buffer_size = 1000;
+        buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
+	if (buffer == NULL) {
+	    perror("malloc failed");
+            exit(1);
+	}
+	out = buffer;
+    }
+    while (*cur != '\0') {
+        if (out - buffer > buffer_size - 100) {
+	    int index = out - buffer;
+
+	    growBuffer();
+	    out = &buffer[index];
+	}
+
+	/*
+	 * By default one have to encode at least '<', '>', '"' and '&' !
+	 * One could try a better encoding using the entities defined and
+	 * used as a compression code !!!.
+	 */
+	if (*cur == '<') {
+	    *out++ = '&';
+	    *out++ = 'l';
+	    *out++ = 't';
+	    *out++ = ';';
+	} else if (*cur == '>') {
+	    *out++ = '&';
+	    *out++ = 'g';
+	    *out++ = 't';
+	    *out++ = ';';
+	} else if (*cur == '&') {
+	    *out++ = '&';
+	    *out++ = 'a';
+	    *out++ = 'm';
+	    *out++ = 'p';
+	    *out++ = ';';
+	} else if (*cur == '"') {
+	    *out++ = '&';
+	    *out++ = 'q';
+	    *out++ = 'u';
+	    *out++ = 'o';
+	    *out++ = 't';
+	    *out++ = ';';
+	} else if (*cur == '\'') {
+	    *out++ = '&';
+	    *out++ = 'a';
+	    *out++ = 'p';
+	    *out++ = 'o';
+	    *out++ = 's';
+	    *out++ = ';';
+	} else {
+	    /*
+	     * default case, just copy !
+	     */
+	    *out++ = *cur;
+	}
+	cur++;
+    }
+    *out++ = 0;
+    return(buffer);
+}
+
+/*
+ * xmlCreateEntitiesTable : create and initialize an enmpty hash table
+ */
+xmlEntitiesTablePtr xmlCreateEntitiesTable(void) {
+    xmlEntitiesTablePtr ret;
+
+    ret = (xmlEntitiesTablePtr) 
+         malloc(sizeof(xmlEntitiesTable));
+    if (ret == NULL) {
+        fprintf(stderr, "xmlCreateEntitiesTable : malloc(%d) failed\n",
+	        sizeof(xmlEntitiesTable));
+        return(NULL);
+    }
+    ret->max_entities = XML_MIN_ENTITIES_TABLE;
+    ret->nb_entities = 0;
+    ret->table = (xmlEntityPtr ) 
+         malloc(ret->max_entities * sizeof(xmlEntity));
+    if (ret == NULL) {
+        fprintf(stderr, "xmlCreateEntitiesTable : malloc(%d) failed\n",
+	        ret->max_entities * sizeof(xmlEntity));
+	free(ret);
+        return(NULL);
+    }
+    return(ret);
+}
+
+/*
+ * xmlFreeEntitiesTable : clean up and free an entities hash table.
+ */
+void xmlFreeEntitiesTable(xmlEntitiesTablePtr table) {
+    int i;
+
+    if (table == NULL) return;
+
+    for (i = 0;i < table->nb_entities;i++) {
+        xmlFreeEntity(&table->table[i]);
+    }
+    free(table->table);
+    free(table);
+}
+
+/*
+ * Dump the content of an entity table to the document output.
+ */
+void xmlDumpEntitiesTable(xmlEntitiesTablePtr table) {
+    int i;
+    xmlEntityPtr cur;
+
+    if (table == NULL) return;
+
+    for (i = 0;i < table->nb_entities;i++) {
+        cur = &table->table[i];
+        switch (cur->type) {
+	    case XML_INTERNAL_GENERAL_ENTITY:
+	        xmlBufferWriteChar("<!ENTITY ");
+		xmlBufferWriteCHAR(cur->name);
+		xmlBufferWriteChar(" \"");
+		xmlBufferWriteCHAR(cur->content);
+		xmlBufferWriteChar("\">\n");
+	        break;
+	    case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
+	        xmlBufferWriteChar("<!ENTITY ");
+		xmlBufferWriteCHAR(cur->name);
+		if (cur->ExternalID != NULL) {
+		     xmlBufferWriteChar(" PUBLIC \"");
+		     xmlBufferWriteCHAR(cur->ExternalID);
+		     xmlBufferWriteChar("\" \"");
+		     xmlBufferWriteCHAR(cur->SystemID);
+		     xmlBufferWriteChar("\"");
+		} else {
+		     xmlBufferWriteChar(" SYSTEM \"");
+		     xmlBufferWriteCHAR(cur->SystemID);
+		     xmlBufferWriteChar("\"");
+		}
+		xmlBufferWriteChar(">\n");
+	        break;
+	    case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
+	        xmlBufferWriteChar("<!ENTITY ");
+		xmlBufferWriteCHAR(cur->name);
+		if (cur->ExternalID != NULL) {
+		     xmlBufferWriteChar(" PUBLIC \"");
+		     xmlBufferWriteCHAR(cur->ExternalID);
+		     xmlBufferWriteChar("\" \"");
+		     xmlBufferWriteCHAR(cur->SystemID);
+		     xmlBufferWriteChar("\"");
+		} else {
+		     xmlBufferWriteChar(" SYSTEM \"");
+		     xmlBufferWriteCHAR(cur->SystemID);
+		     xmlBufferWriteChar("\"");
+		}
+		if (cur->content != NULL) { /* Should be true ! */
+		    xmlBufferWriteChar(" NDATA ");
+		    xmlBufferWriteCHAR(cur->content);
+		}
+		xmlBufferWriteChar(">\n");
+	        break;
+	    case XML_INTERNAL_PARAMETER_ENTITY:
+	        xmlBufferWriteChar("<!ENTITY % ");
+		xmlBufferWriteCHAR(cur->name);
+		xmlBufferWriteChar(" \"");
+		xmlBufferWriteCHAR(cur->content);
+		xmlBufferWriteChar("\">\n");
+	        break;
+	    case XML_EXTERNAL_PARAMETER_ENTITY:
+	        xmlBufferWriteChar("<!ENTITY % ");
+		xmlBufferWriteCHAR(cur->name);
+		if (cur->ExternalID != NULL) {
+		     xmlBufferWriteChar(" PUBLIC \"");
+		     xmlBufferWriteCHAR(cur->ExternalID);
+		     xmlBufferWriteChar("\" \"");
+		     xmlBufferWriteCHAR(cur->SystemID);
+		     xmlBufferWriteChar("\"");
+		} else {
+		     xmlBufferWriteChar(" SYSTEM \"");
+		     xmlBufferWriteCHAR(cur->SystemID);
+		     xmlBufferWriteChar("\"");
+		}
+		xmlBufferWriteChar(">\n");
+	        break;
+	    default:
+	        fprintf(stderr,
+		    "xmlDumpEntitiesTable: internal: unknown type %d\n",
+		        cur->type);
+	}
+    }
+}
diff --git a/entities.h b/entities.h
new file mode 100644
index 0000000..0065245
--- /dev/null
+++ b/entities.h
@@ -0,0 +1,70 @@
+/*
+ * entities.h : interface for the XML entities handking
+ *
+ * See Copyright for the status of this software.
+ *
+ * $Id$
+ */
+
+#ifndef __XML_ENTITIES_H__
+#define __XML_ENTITIES_H__
+#include "parser.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define XML_INTERNAL_GENERAL_ENTITY		1
+#define XML_EXTERNAL_GENERAL_PARSED_ENTITY	2
+#define XML_EXTERNAL_GENERAL_UNPARSED_ENTITY	3
+#define XML_INTERNAL_PARAMETER_ENTITY		4
+#define XML_EXTERNAL_PARAMETER_ENTITY		5
+
+/*
+ * An unit of storage for an entity, contains the string, the value
+ * and the linkind data needed for the linking in the hash table.
+ */
+
+typedef struct xmlEntity {
+    int type;			/* The entity type */
+    int len;			/* The lenght of the name */
+    const CHAR    *name;	/* Name of the entity */
+    const CHAR    *ExternalID;	/* External identifier for PUBLIC Entity */
+    const CHAR    *SystemID;	/* URI for a SYSTEM or PUBLIC Entity */
+    CHAR *content;		/* The entity content or ndata if unparsed */
+} xmlEntity, *xmlEntityPtr;
+
+/*
+ * ALl entities are stored in a table there is one table per DTD
+ * and one extra per document.
+ */
+
+#define XML_MIN_ENTITIES_TABLE	32
+
+typedef struct xmlEntitiesTable {
+    int nb_entities;		/* number of elements stored */
+    int max_entities;		/* maximum number of elements */
+    xmlEntityPtr table;		/* the table of entities */
+} xmlEntitiesTable, *xmlEntitiesTablePtr;
+
+/*
+ * External functions :
+ */
+
+extern void xmlAddDocEntity(xmlDocPtr doc, const CHAR *name, int type,
+              const CHAR *ExternalID, const CHAR *SystemID, CHAR *content);
+extern void xmlAddDtdEntity(xmlDocPtr doc, const CHAR *name, int type,
+              const CHAR *ExternalID, const CHAR *SystemID, CHAR *content);
+extern xmlEntityPtr xmlGetDocEntity(xmlDocPtr doc, const CHAR *name);
+extern xmlEntityPtr xmlGetDtdEntity(xmlDocPtr doc, const CHAR *name);
+extern CHAR *xmlEncodeEntities(xmlDocPtr doc, const CHAR *input);
+extern xmlEntitiesTablePtr xmlCreateEntitiesTable(void);
+extern void xmlFreeEntitiesTable(xmlEntitiesTablePtr table);
+extern void xmlDumpEntitiesTable(xmlEntitiesTablePtr table);
+
+#ifdef __cplusplus
+}
+#endif
+
+# endif /* __XML_ENTITIES_H__ */
diff --git a/error.c b/error.c
new file mode 100644
index 0000000..4c4bac5
--- /dev/null
+++ b/error.c
@@ -0,0 +1,93 @@
+/*
+ * error.c: module displaying errors
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include "parser.h"
+
+/*
+ * Display and format error messages.
+ */
+void xmlParserError(xmlParserCtxtPtr ctxt, const char *msg, ...) {
+    const CHAR *cur, *base;
+    va_list args;
+    int n;
+
+    va_start(args, msg);
+    if (ctxt->input->filename)
+        fprintf(stderr, "%s:%d: ", ctxt->input->filename,
+	        ctxt->input->line);
+    else
+        fprintf(stderr, "line %d: ", ctxt->input->line);
+        
+    fprintf(stderr, "error: ");
+    vfprintf(stderr, msg, args);
+    va_end(ap);
+    cur = ctxt->input->cur;
+    base = ctxt->input->base;
+    while ((*cur == '\n') || (*cur == '\r')) {
+	cur--;
+	base--;
+    }
+    n = 0;
+    while ((n++ < 60) && (cur >= base) && (*cur != '\n') && (*cur != '\r'))
+        cur--;
+    if ((*cur == '\n') || (*cur == '\r')) cur++;
+    base = cur;
+    n = 0;
+    while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
+        fprintf(stderr, "%c", (unsigned char) *cur++);
+	n++;
+    }
+    fprintf(stderr, "\n");
+    cur = ctxt->input->cur;
+    while ((*cur == '\n') || (*cur == '\r'))
+	cur--;
+    n = 0;
+    while ((cur != base) && (n++ < 60)) {
+        fprintf(stderr, " ");
+        base++;
+    }
+    fprintf(stderr,"^\n");
+}
+
+/*
+ * Display and format error messages.
+ */
+void xmlParserWarning(xmlParserCtxtPtr ctxt, const char *msg, ...) {
+    const CHAR *cur, *base;
+    va_list args;
+    int n;
+
+    va_start(args, msg);
+    if (ctxt->input->filename)
+        fprintf(stderr, "%s:%d: ", ctxt->input->filename,
+	        ctxt->input->line);
+    else
+        fprintf(stderr, "line %d: ", ctxt->input->line);
+        
+    fprintf(stderr, "warning: ");
+    vfprintf(stderr, msg, args);
+    va_end(ap);
+    cur = ctxt->input->cur;
+    base = ctxt->input->base;
+    n = 0;
+    while ((n++ < 60) && (cur >= base) && (*cur != '\n') && (*cur != '\r'))
+        cur--;
+    if ((*cur != '\n') || (*cur != '\r')) cur++;
+    base = cur;
+    n = 0;
+    while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
+        fprintf(stderr, "%c", (unsigned char) *cur++);
+	n++;
+    }
+    fprintf(stderr, "\n");
+    cur = ctxt->input->cur;
+    n = 0;
+    while ((cur != base) && (n++ < 60)) {
+        fprintf(stderr, " ");
+        base++;
+    }
+    fprintf(stderr,"^\n");
+}
diff --git a/include/libxml/entities.h b/include/libxml/entities.h
new file mode 100644
index 0000000..0065245
--- /dev/null
+++ b/include/libxml/entities.h
@@ -0,0 +1,70 @@
+/*
+ * entities.h : interface for the XML entities handking
+ *
+ * See Copyright for the status of this software.
+ *
+ * $Id$
+ */
+
+#ifndef __XML_ENTITIES_H__
+#define __XML_ENTITIES_H__
+#include "parser.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define XML_INTERNAL_GENERAL_ENTITY		1
+#define XML_EXTERNAL_GENERAL_PARSED_ENTITY	2
+#define XML_EXTERNAL_GENERAL_UNPARSED_ENTITY	3
+#define XML_INTERNAL_PARAMETER_ENTITY		4
+#define XML_EXTERNAL_PARAMETER_ENTITY		5
+
+/*
+ * An unit of storage for an entity, contains the string, the value
+ * and the linkind data needed for the linking in the hash table.
+ */
+
+typedef struct xmlEntity {
+    int type;			/* The entity type */
+    int len;			/* The lenght of the name */
+    const CHAR    *name;	/* Name of the entity */
+    const CHAR    *ExternalID;	/* External identifier for PUBLIC Entity */
+    const CHAR    *SystemID;	/* URI for a SYSTEM or PUBLIC Entity */
+    CHAR *content;		/* The entity content or ndata if unparsed */
+} xmlEntity, *xmlEntityPtr;
+
+/*
+ * ALl entities are stored in a table there is one table per DTD
+ * and one extra per document.
+ */
+
+#define XML_MIN_ENTITIES_TABLE	32
+
+typedef struct xmlEntitiesTable {
+    int nb_entities;		/* number of elements stored */
+    int max_entities;		/* maximum number of elements */
+    xmlEntityPtr table;		/* the table of entities */
+} xmlEntitiesTable, *xmlEntitiesTablePtr;
+
+/*
+ * External functions :
+ */
+
+extern void xmlAddDocEntity(xmlDocPtr doc, const CHAR *name, int type,
+              const CHAR *ExternalID, const CHAR *SystemID, CHAR *content);
+extern void xmlAddDtdEntity(xmlDocPtr doc, const CHAR *name, int type,
+              const CHAR *ExternalID, const CHAR *SystemID, CHAR *content);
+extern xmlEntityPtr xmlGetDocEntity(xmlDocPtr doc, const CHAR *name);
+extern xmlEntityPtr xmlGetDtdEntity(xmlDocPtr doc, const CHAR *name);
+extern CHAR *xmlEncodeEntities(xmlDocPtr doc, const CHAR *input);
+extern xmlEntitiesTablePtr xmlCreateEntitiesTable(void);
+extern void xmlFreeEntitiesTable(xmlEntitiesTablePtr table);
+extern void xmlDumpEntitiesTable(xmlEntitiesTablePtr table);
+
+#ifdef __cplusplus
+}
+#endif
+
+# endif /* __XML_ENTITIES_H__ */
diff --git a/include/libxml/parser.h b/include/libxml/parser.h
new file mode 100644
index 0000000..a25e70a
--- /dev/null
+++ b/include/libxml/parser.h
@@ -0,0 +1,168 @@
+/*
+ * parser.h : constants and stuff related to the XML parser.
+ *
+ * See Copyright for the status of this software.
+ *
+ * $Id$
+ */
+
+#ifndef __XML_PARSER_H__
+#define __XML_PARSER_H__
+
+#include "tree.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Constants.
+ */
+#define XML_DEFAULT_VERSION	"1.0"
+
+typedef struct xmlParserInput {
+    const char *filename;             /* The file analyzed, if any */
+    const CHAR *base;                 /* Base of the array to parse */
+    const CHAR *cur;                  /* Current char being parsed */
+    int line;                         /* Current line */
+    int col;                          /* Current column */
+} xmlParserInput, *xmlParserInputPtr;
+
+typedef struct xmlParserNodeInfo {
+  const struct xmlNode* node;
+  /* Position & line # that text that created the node begins & ends on */
+  unsigned long begin_pos;
+  unsigned long begin_line;
+  unsigned long end_pos;
+  unsigned long end_line;
+} xmlParserNodeInfo;
+
+typedef struct xmlParserNodeInfoSeq {
+  unsigned long maximum;
+  unsigned long length;
+  xmlParserNodeInfo* buffer;
+} xmlParserNodeInfoSeq, *xmlParserNodeInfoSeqPtr;
+
+typedef struct xmlParserCtxt {
+    struct xmlSAXHandler *sax;        /* The SAX handler */
+    xmlDocPtr doc;                    /* the document being built */
+
+    /* Input stream stack */
+    xmlParserInputPtr  input;         /* Current input stream */
+    int                inputNr;       /* Number of current input streams */
+    int                inputMax;      /* Max number of input streams */
+    xmlParserInputPtr *inputTab;      /* stack of inputs */
+
+    /* Node analysis stack */
+    xmlNodePtr         node;          /* Current parsed Node */
+    int                nodeNr;        /* Depth of the parsing stack */
+    int                nodeMax;       /* Max depth of the parsing stack */
+    xmlNodePtr        *nodeTab;       /* array of nodes */
+
+    int record_info;                  /* Whether node info should be kept */
+    xmlParserNodeInfoSeq node_seq;    /* info about each node parsed */
+} xmlParserCtxt, *xmlParserCtxtPtr;
+
+/*
+ * a SAX Locator.
+ */
+
+typedef struct xmlSAXLocator {
+    const CHAR *(*getPublicId)(xmlParserCtxtPtr ctxt);
+    const CHAR *(*getSystemId)(xmlParserCtxtPtr ctxt);
+    int (*getLineNumber)(xmlParserCtxtPtr ctxt);
+    int (*getColumnNumber)(xmlParserCtxtPtr ctxt);
+} xmlSAXLocator, *xmlSAXLocatorPtr;
+
+/*
+ * a SAX Exception.
+ */
+
+typedef xmlParserInputPtr (*resolveEntitySAXFunc) (xmlParserCtxtPtr ctxt,
+			    const CHAR *publicId, const CHAR *systemId);
+typedef void (*notationDeclSAXFunc)(xmlParserCtxtPtr ctxt, const CHAR *name,
+			    const CHAR *publicId, const CHAR *systemId);
+typedef void (*unparsedEntityDeclSAXFunc)(xmlParserCtxtPtr ctxt,
+                            const CHAR *name, const CHAR *publicId,
+			    const CHAR *systemId, const CHAR *notationName);
+typedef void (*setDocumentLocatorSAXFunc) (xmlParserCtxtPtr ctxt,
+                            xmlSAXLocatorPtr loc);
+typedef void (*startDocumentSAXFunc) (xmlParserCtxtPtr ctxt);
+typedef void (*endDocumentSAXFunc) (xmlParserCtxtPtr ctxt);
+typedef void (*startElementSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *name);
+typedef void (*endElementSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *name);
+typedef void (*charactersSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *ch,
+		            int start, int len);
+typedef void (*ignorableWhitespaceSAXFunc) (xmlParserCtxtPtr ctxt,
+			    const CHAR *ch, int start, int len);
+typedef void (*processingInstructionSAXFunc) (xmlParserCtxtPtr ctxt,
+                            const CHAR *target, const CHAR *data);
+typedef void (*warningSAXFunc) (xmlParserCtxtPtr ctxt, const char *msg, ...);
+typedef void (*errorSAXFunc) (xmlParserCtxtPtr ctxt, const char *msg, ...);
+typedef void (*fatalErrorSAXFunc) (xmlParserCtxtPtr ctxt, const char *msg, ...);
+
+typedef struct xmlSAXHandler {
+    resolveEntitySAXFunc resolveEntity;
+    notationDeclSAXFunc notationDecl;
+    unparsedEntityDeclSAXFunc unparsedEntityDecl;
+    setDocumentLocatorSAXFunc setDocumentLocator;
+    startDocumentSAXFunc startDocument;
+    endDocumentSAXFunc endDocument;
+    startElementSAXFunc startElement;
+    endElementSAXFunc endElement;
+    charactersSAXFunc characters;
+    ignorableWhitespaceSAXFunc ignorableWhitespace;
+    processingInstructionSAXFunc processingInstruction;
+    warningSAXFunc warning;
+    errorSAXFunc error;
+    fatalErrorSAXFunc fatalError;
+} xmlSAXHandler, *xmlSAXHandlerPtr;
+
+/*
+ * Global variables: just the SAX interface tables we are looking for full
+ *      reentrancy of the code !
+ */
+xmlSAXLocator xmlDefaultSAXLocator;
+xmlSAXHandler xmlDefaultSAXHandler;
+
+/*
+ * Interfaces
+ */
+extern int xmlParseDocument(xmlParserCtxtPtr ctxt);
+extern xmlDocPtr xmlParseDoc(CHAR *cur);
+extern xmlDocPtr xmlParseMemory(char *buffer, int size);
+extern xmlDocPtr xmlParseFile(const char *filename);
+extern CHAR *xmlStrdup(const CHAR *input);
+extern CHAR *xmlStrndup(const CHAR *input, int n);
+extern CHAR *xmlStrchr(const CHAR *str, CHAR val);
+extern int xmlStrcmp(const CHAR *str1, const CHAR *str2);
+extern int xmlStrncmp(const CHAR *str1, const CHAR *str2, int len);
+extern int xmlStrlen(const CHAR *str);
+extern CHAR *xmlStrcat(CHAR *cur, const CHAR *add);
+extern CHAR *xmlStrncat(CHAR *cur, const CHAR *add, int len);
+
+extern void xmlInitParserCtxt(xmlParserCtxtPtr ctx);
+extern void xmlClearParserCtxt(xmlParserCtxtPtr ctx);
+extern void xmlSetupParserForBuffer(xmlParserCtxtPtr ctx, const CHAR* buffer,
+                                    const char* filename);
+
+extern void xmlParserError(xmlParserCtxtPtr ctxt, const char *msg, ...);
+
+extern const xmlParserNodeInfo* xmlParserFindNodeInfo(const xmlParserCtxt* c,
+                                                      const xmlNode* node);
+extern void xmlInitNodeInfoSeq(xmlParserNodeInfoSeqPtr seq);
+extern void xmlClearNodeInfoSeq(xmlParserNodeInfoSeqPtr seq);
+unsigned long xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeq* seq,
+                                         const xmlNode* node);
+extern void xmlParserAddNodeInfo(xmlParserCtxtPtr ctx,
+                                 const xmlParserNodeInfo* info);
+
+extern void xmlParserWarning(xmlParserCtxtPtr ctxt, const char *msg, ...);
+extern void xmlParserError(xmlParserCtxtPtr ctxt, const char *msg, ...);
+extern void xmlDefaultSAXHandlerInit(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_PARSER_H__ */
+
diff --git a/include/libxml/tree.h b/include/libxml/tree.h
new file mode 100644
index 0000000..7a48a9b
--- /dev/null
+++ b/include/libxml/tree.h
@@ -0,0 +1,180 @@
+/*
+ * tree.h : describes the structures found in an tree resulting
+ *          from an XML parsing.
+ *
+ * See Copyright for the status of this software.
+ *
+ * $Id$
+ */
+
+#ifndef __XML_TREE_H__
+#define __XML_TREE_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Type definitions
+ */
+#ifdef UNICODE
+typedef unsigned short CHAR;
+#else
+typedef unsigned char CHAR;
+#endif
+
+/*
+ * a DTD Notation definition
+ * TODO !!!!
+ */
+
+/*
+ * a DTD Attribute definition
+ * TODO !!!!
+ */
+
+/*
+ * a DTD Element definition.
+ */
+#define XML_ELEMENT_TYPE_EMPTY		1
+#define XML_ELEMENT_TYPE_ANY		2
+#define XML_ELEMENT_TYPE_MIXED		3
+#define XML_ELEMENT_TYPE_ELEMENT	4
+
+typedef struct xmlElement {
+    const CHAR    *name;	/* Element name */
+    int            type;	/* type (too simple, to extend ...) */
+    /* TODO !!! more needed */
+} xmlElement, *xmlElementPtr;
+
+/*
+ * An XML namespace.
+ * Note that prefix == NULL is valid, it defines the default namespace
+ * within the subtree (until overriden).
+ */
+
+#define XML_GLOBAL_NAMESPACE		1 /* old style global namespace */
+#define XML_LOCAL_NAMESPACE		2 /* new style local scoping */
+
+typedef struct xmlNs {
+    struct xmlNs  *next;	/* next Ns link for this node  */
+    int            type;	/* global or local */
+    const CHAR    *href;	/* URL for the namespace */
+    const CHAR    *prefix;	/* prefix for the namespace */
+} xmlNs, *xmlNsPtr;
+
+/*
+ * An XML DtD, as defined by <!DOCTYPE.
+ */
+typedef struct xmlDtd {
+    const CHAR    *name;	/* Name of the DTD */
+    const CHAR    *ExternalID;	/* External identifier for PUBLIC DTD */
+    const CHAR    *SystemID;	/* URI for a SYSTEM or PUBLIC DTD */
+    void          *elements;    /* Hash table for elements if any */
+    void          *entities;    /* Hash table for entities if any */
+    /* struct xmlDtd *next;	 * next  link for this document  */
+} xmlDtd, *xmlDtdPtr;
+
+/*
+ * A attribute of an XML node.
+ */
+typedef struct xmlAttr {
+    struct xmlNode *node;	/* attr->node link */
+    struct xmlAttr *next;	/* parent->childs link */
+    const CHAR     *name;       /* the name of the property */
+    const CHAR     *value;      /* the value of the property */
+} xmlAttr, *xmlAttrPtr;
+
+/*
+ * A node in an XML tree.
+ */
+#define XML_TYPE_TEXT		1
+#define XML_TYPE_COMMENT	2
+#define XML_TYPE_ENTITY		3
+
+typedef struct xmlNode {
+    struct xmlNode *parent;	/* child->parent link */
+    struct xmlNode *next;	/* next sibling link  */
+    struct xmlNode *childs;	/* parent->childs link */
+    struct xmlAttr *properties;	/* properties list */
+    int             type;	/* type number in the DTD */
+    const CHAR     *name;       /* the name of the node, or the entity */
+    xmlNs          *ns;         /* pointer to the associated namespace */
+    xmlNs          *nsDef;      /* namespace definitions on this node */
+    CHAR           *content;    /* the content */
+} xmlNode, *xmlNodePtr;
+
+/*
+ * An XML document.
+ */
+typedef struct xmlDoc {
+    char           *name;	/* name/filename/URI of the document */
+    const CHAR     *version;	/* the XML version string */
+    const CHAR     *encoding;   /* encoding, if any */
+    int             standalone; /* standalone document (no external refs) */
+    struct xmlDtd  *dtd;	/* the document DTD if available */
+    struct xmlNs   *oldNs;	/* Global namespace, the old way */
+    void          *entities;    /* Hash table for general entities if any */
+    struct xmlNode *root;	/* the document tree */
+} xmlDoc, *xmlDocPtr;
+
+/*
+ * Variables.
+ */
+extern xmlNsPtr baseDTD;
+extern int oldXMLWDcompatibility;/* maintain compatibility with old WD */
+extern int xmlIndentTreeOutput;  /* try to indent the tree dumps */
+
+/*
+ * Functions.
+ */
+extern xmlDtdPtr xmlNewDtd(xmlDocPtr doc, const CHAR *name,
+                    const CHAR *ExternalID, const CHAR *SystemID);
+extern void xmlFreeDtd(xmlDtdPtr cur);
+extern xmlNsPtr xmlNewGlobalNs(xmlDocPtr doc, const CHAR *href, const CHAR *AS);
+extern xmlNsPtr xmlNewNs(xmlNodePtr node, const CHAR *href, const CHAR *AS);
+extern void xmlFreeNs(xmlNsPtr cur);
+extern xmlDocPtr xmlNewDoc(const CHAR *version);
+extern void xmlFreeDoc(xmlDocPtr cur);
+extern xmlAttrPtr xmlNewProp(xmlNodePtr node, const CHAR *name,
+                             const CHAR *value);
+extern xmlAttrPtr xmlSetProp(xmlNodePtr node, const CHAR *name,
+                             const CHAR *value);
+extern const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name);
+extern void xmlFreePropList(xmlAttrPtr cur);
+extern void xmlFreeProp(xmlAttrPtr cur);
+extern xmlNodePtr xmlNewNode(xmlNsPtr ns, const CHAR *name, CHAR *content);
+extern xmlNodePtr xmlNewText(const CHAR *content);
+extern xmlNodePtr xmlNewTextLen(const CHAR *content, int len);
+extern xmlNodePtr xmlNewComment(CHAR *content);
+extern xmlNodePtr xmlAddChild(xmlNodePtr parent, xmlNodePtr cur);
+extern xmlNodePtr xmlGetLastChild(xmlNodePtr node);
+extern int xmlNodeIsText(xmlNodePtr node);
+extern void xmlTextConcat(xmlNodePtr node, const CHAR *content, int len);
+extern void xmlFreeNodeList(xmlNodePtr cur);
+extern void xmlFreeNode(xmlNodePtr cur);
+extern void xmlNodeSetContent(xmlNodePtr cur, const CHAR *content);
+extern void xmlNodeSetContentLen(xmlNodePtr cur, const CHAR *content, int len);
+extern void xmlNodeAddContent(xmlNodePtr cur, const CHAR *content);
+extern void xmlNodeAddContentLen(xmlNodePtr cur, const CHAR *content, int len);
+extern xmlNsPtr xmlSearchNs(xmlDocPtr doc, xmlNodePtr node,
+                            const CHAR *nameSpace);
+extern xmlNsPtr xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node,
+                                  const CHAR *href);
+extern void xmlSetNs(xmlNodePtr node, xmlNsPtr ns);
+extern xmlNodePtr xmlNewChild(xmlNodePtr parent, xmlNsPtr ns,
+                              const CHAR *name, CHAR *content);
+
+extern void xmlDocDumpMemory(xmlDocPtr cur, CHAR**mem, int *size);
+extern void xmlDocDump(FILE *f, xmlDocPtr doc);
+extern void xmlBufferWriteCHAR(const CHAR *string);
+extern void xmlBufferWriteChar(const char *string);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_TREE_H__ */
+
diff --git a/parser.c b/parser.c
new file mode 100644
index 0000000..bb24dd5
--- /dev/null
+++ b/parser.c
@@ -0,0 +1,3334 @@
+/*
+ * parser.c : an XML 1.0 non-verifying parser
+ *
+ * See Copyright for the status of this software.
+ *
+ * $Id$
+ */
+
+#ifdef WIN32
+#define HAVE_FCNTL_H
+#include <io.h>
+#else
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h> /* for memset() only */
+#include <malloc.h>
+#include <sys/stat.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+#include "tree.h"
+#include "parser.h"
+#include "entities.h"
+
+/************************************************************************
+ *									*
+ * 		Parser stacks related functions and macros		*
+ *									*
+ ************************************************************************/
+/*
+ * Generic function for accessing stacks in the Parser Context
+ */
+
+#define PUSH_AND_POP(type, name)					\
+int name##Push(xmlParserCtxtPtr ctxt, type value) {			\
+    if (ctxt->name##Nr >= ctxt->name##Max) {				\
+	ctxt->name##Max *= 2;						\
+        ctxt->name##Tab = (void *) realloc(ctxt->name##Tab,		\
+	             ctxt->name##Max * sizeof(ctxt->name##Tab[0]));	\
+        if (ctxt->name##Tab == NULL) {					\
+	    fprintf(stderr, "realloc failed !\n");			\
+	    exit(1);							\
+	}								\
+    }									\
+    ctxt->name##Tab[ctxt->name##Nr] = value;				\
+    ctxt->name = value;							\
+    return(ctxt->name##Nr++);						\
+}									\
+type name##Pop(xmlParserCtxtPtr ctxt) {					\
+    if (ctxt->name##Nr <= 0) return(0);					\
+    ctxt->name##Nr--;							\
+    ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1];			\
+    return(ctxt->name);							\
+}									\
+
+PUSH_AND_POP(xmlParserInputPtr, input)
+PUSH_AND_POP(xmlNodePtr, node)
+
+/*************
+#define CUR (*(ctxt->input->cur) ? *(ctxt->input->cur) : xmlPopInput(ctxt))
+#define NEXT (((*(ctxt->input->cur) == '\n') ?				\
+		(ctxt->input->line++, ctxt->input->col = 1) :		\
+		(ctxt->input->col++)), ctxt->input->cur++)
+ *************/
+
+#define CUR (*ctxt->input->cur)
+#define NEXT ((*ctxt->input->cur) ?					\
+                (((*(ctxt->input->cur) == '\n') ?			\
+		    (ctxt->input->line++, ctxt->input->col = 1) :	\
+		    (ctxt->input->col++)), ctxt->input->cur++) :	\
+		(xmlPopInput(ctxt), ctxt->input->cur))
+
+#define CUR_PTR ctxt->input->cur
+
+#define NXT(val) ctxt->input->cur[(val)]
+
+#define SKIP(val) ctxt->input->cur += (val)
+#define SKIP_BLANKS 							\
+    while (IS_BLANK(*(ctxt->input->cur))) NEXT
+
+
+/*
+ * xmlPopInput: the current input pointed by ctxt->input came to an end
+ *          pop it and return the next char.
+ *
+ * TODO A deallocation of the popped Input structure is needed
+ */
+CHAR xmlPopInput(xmlParserCtxtPtr ctxt) {
+    if (ctxt->inputNr == 1) return(0); /* End of main Input */
+    inputPop(ctxt);
+    return(CUR);
+}
+
+/*
+ * xmlPushInput: switch to a new input stream which is stacked on top
+ *               of the previous one(s).
+ */
+void xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
+    if (input == NULL) return;
+    inputPush(ctxt, input);
+}
+
+/*
+ * Create a new input stream based on a memory buffer.
+ */
+void xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
+    xmlParserInputPtr input;
+
+    if (entity == NULL) {
+        xmlParserError(ctxt,
+	      "internal: xmlNewEntityInputStream entity = NULL\n");
+	return;
+    }
+    if (entity->content == NULL) {
+        xmlParserError(ctxt,
+	      "internal: xmlNewEntityInputStream entity->input = NULL\n");
+	return;
+    }
+    input = (xmlParserInputPtr) malloc(sizeof(xmlParserInput));
+    if (input == NULL) {
+	xmlParserError(ctxt, "malloc: couldn't allocate a new input stream\n");
+	return;
+    }
+    input->filename = entity->SystemID; /* TODO !!! char <- CHAR */
+    input->base = entity->content;
+    input->cur = entity->content;
+    input->line = 1;
+    input->col = 1;
+    xmlPushInput(ctxt, input);
+}
+
+/*
+ * A few macros needed to help building the parser.
+ */
+
+#ifdef UNICODE
+/************************************************************************
+ *									*
+ * UNICODE version of the macros.      					*
+ *									*
+ ************************************************************************/
+/*
+ * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
+ *                  | [#x10000-#x10FFFF]
+ * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
+ */
+#define IS_CHAR(c)							\
+    (((c) == 0x09) || ((c) == 0x0a) || ((c) == 0x0d) ||			\
+     (((c) >= 0x20) && ((c) != 0xFFFE) && ((c) != 0xFFFF)))
+
+/*
+ * [3] S ::= (#x20 | #x9 | #xD | #xA)+
+ */
+#define IS_BLANK(c) (((c) == 0x20) || ((c) == 0x09) || ((c) == 0xa) ||	\
+                     ((c) == 0x0D))
+
+/*
+ * [85] BaseChar ::= ... long list see REC ...
+ *
+ * VI is your friend !
+ * :1,$ s/\[#x\([0-9A-Z]*\)-#x\([0-9A-Z]*\)\]/     (((c) >= 0x\1) \&\& ((c) <= 0x\2)) ||/
+ * and 
+ * :1,$ s/#x\([0-9A-Z]*\)/     ((c) == 0x\1) ||/
+ */
+#define IS_BASECHAR(c)							\
+     ((((c) >= 0x0041) && ((c) <= 0x005A)) ||				\
+      (((c) >= 0x0061) && ((c) <= 0x007A)) ||				\
+      (((c) >= 0x00C0) && ((c) <= 0x00D6)) ||				\
+      (((c) >= 0x00D8) && ((c) <= 0x00F6)) ||				\
+      (((c) >= 0x00F8) && ((c) <= 0x00FF)) ||				\
+      (((c) >= 0x0100) && ((c) <= 0x0131)) ||				\
+      (((c) >= 0x0134) && ((c) <= 0x013E)) ||				\
+      (((c) >= 0x0141) && ((c) <= 0x0148)) ||				\
+      (((c) >= 0x014A) && ((c) <= 0x017E)) ||				\
+      (((c) >= 0x0180) && ((c) <= 0x01C3)) ||				\
+      (((c) >= 0x01CD) && ((c) <= 0x01F0)) ||				\
+      (((c) >= 0x01F4) && ((c) <= 0x01F5)) ||				\
+      (((c) >= 0x01FA) && ((c) <= 0x0217)) ||				\
+      (((c) >= 0x0250) && ((c) <= 0x02A8)) ||				\
+      (((c) >= 0x02BB) && ((c) <= 0x02C1)) ||				\
+      ((c) == 0x0386) ||						\
+      (((c) >= 0x0388) && ((c) <= 0x038A)) ||				\
+      ((c) == 0x038C) ||						\
+      (((c) >= 0x038E) && ((c) <= 0x03A1)) ||				\
+      (((c) >= 0x03A3) && ((c) <= 0x03CE)) ||				\
+      (((c) >= 0x03D0) && ((c) <= 0x03D6)) ||				\
+      ((c) == 0x03DA) ||						\
+      ((c) == 0x03DC) ||						\
+      ((c) == 0x03DE) ||						\
+      ((c) == 0x03E0) ||						\
+      (((c) >= 0x03E2) && ((c) <= 0x03F3)) ||				\
+      (((c) >= 0x0401) && ((c) <= 0x040C)) ||				\
+      (((c) >= 0x040E) && ((c) <= 0x044F)) ||				\
+      (((c) >= 0x0451) && ((c) <= 0x045C)) ||				\
+      (((c) >= 0x045E) && ((c) <= 0x0481)) ||				\
+      (((c) >= 0x0490) && ((c) <= 0x04C4)) ||				\
+      (((c) >= 0x04C7) && ((c) <= 0x04C8)) ||				\
+      (((c) >= 0x04CB) && ((c) <= 0x04CC)) ||				\
+      (((c) >= 0x04D0) && ((c) <= 0x04EB)) ||				\
+      (((c) >= 0x04EE) && ((c) <= 0x04F5)) ||				\
+      (((c) >= 0x04F8) && ((c) <= 0x04F9)) ||				\
+      (((c) >= 0x0531) && ((c) <= 0x0556)) ||				\
+      ((c) == 0x0559) ||						\
+      (((c) >= 0x0561) && ((c) <= 0x0586)) ||				\
+      (((c) >= 0x05D0) && ((c) <= 0x05EA)) ||				\
+      (((c) >= 0x05F0) && ((c) <= 0x05F2)) ||				\
+      (((c) >= 0x0621) && ((c) <= 0x063A)) ||				\
+      (((c) >= 0x0641) && ((c) <= 0x064A)) ||				\
+      (((c) >= 0x0671) && ((c) <= 0x06B7)) ||				\
+      (((c) >= 0x06BA) && ((c) <= 0x06BE)) ||				\
+      (((c) >= 0x06C0) && ((c) <= 0x06CE)) ||				\
+      (((c) >= 0x06D0) && ((c) <= 0x06D3)) ||				\
+      ((c) == 0x06D5) ||						\
+      (((c) >= 0x06E5) && ((c) <= 0x06E6)) ||				\
+      (((c) >= 0x0905) && ((c) <= 0x0939)) ||				\
+      ((c) == 0x093D) ||						\
+      (((c) >= 0x0958) && ((c) <= 0x0961)) ||				\
+      (((c) >= 0x0985) && ((c) <= 0x098C)) ||				\
+      (((c) >= 0x098F) && ((c) <= 0x0990)) ||				\
+      (((c) >= 0x0993) && ((c) <= 0x09A8)) ||				\
+      (((c) >= 0x09AA) && ((c) <= 0x09B0)) ||				\
+      ((c) == 0x09B2) ||						\
+      (((c) >= 0x09B6) && ((c) <= 0x09B9)) ||				\
+      (((c) >= 0x09DC) && ((c) <= 0x09DD)) ||				\
+      (((c) >= 0x09DF) && ((c) <= 0x09E1)) ||				\
+      (((c) >= 0x09F0) && ((c) <= 0x09F1)) ||				\
+      (((c) >= 0x0A05) && ((c) <= 0x0A0A)) ||				\
+      (((c) >= 0x0A0F) && ((c) <= 0x0A10)) ||				\
+      (((c) >= 0x0A13) && ((c) <= 0x0A28)) ||				\
+      (((c) >= 0x0A2A) && ((c) <= 0x0A30)) ||				\
+      (((c) >= 0x0A32) && ((c) <= 0x0A33)) ||				\
+      (((c) >= 0x0A35) && ((c) <= 0x0A36)) ||				\
+      (((c) >= 0x0A38) && ((c) <= 0x0A39)) ||				\
+      (((c) >= 0x0A59) && ((c) <= 0x0A5C)) ||				\
+      ((c) == 0x0A5E) ||						\
+      (((c) >= 0x0A72) && ((c) <= 0x0A74)) ||				\
+      (((c) >= 0x0A85) && ((c) <= 0x0A8B)) ||				\
+      ((c) == 0x0A8D) ||						\
+      (((c) >= 0x0A8F) && ((c) <= 0x0A91)) ||				\
+      (((c) >= 0x0A93) && ((c) <= 0x0AA8)) ||				\
+      (((c) >= 0x0AAA) && ((c) <= 0x0AB0)) ||				\
+      (((c) >= 0x0AB2) && ((c) <= 0x0AB3)) ||				\
+      (((c) >= 0x0AB5) && ((c) <= 0x0AB9)) ||				\
+      ((c) == 0x0ABD) ||						\
+      ((c) == 0x0AE0) ||						\
+      (((c) >= 0x0B05) && ((c) <= 0x0B0C)) ||				\
+      (((c) >= 0x0B0F) && ((c) <= 0x0B10)) ||				\
+      (((c) >= 0x0B13) && ((c) <= 0x0B28)) ||				\
+      (((c) >= 0x0B2A) && ((c) <= 0x0B30)) ||				\
+      (((c) >= 0x0B32) && ((c) <= 0x0B33)) ||				\
+      (((c) >= 0x0B36) && ((c) <= 0x0B39)) ||				\
+      ((c) == 0x0B3D) ||						\
+      (((c) >= 0x0B5C) && ((c) <= 0x0B5D)) ||				\
+      (((c) >= 0x0B5F) && ((c) <= 0x0B61)) ||				\
+      (((c) >= 0x0B85) && ((c) <= 0x0B8A)) ||				\
+      (((c) >= 0x0B8E) && ((c) <= 0x0B90)) ||				\
+      (((c) >= 0x0B92) && ((c) <= 0x0B95)) ||				\
+      (((c) >= 0x0B99) && ((c) <= 0x0B9A)) ||				\
+      ((c) == 0x0B9C) ||						\
+      (((c) >= 0x0B9E) && ((c) <= 0x0B9F)) ||				\
+      (((c) >= 0x0BA3) && ((c) <= 0x0BA4)) ||				\
+      (((c) >= 0x0BA8) && ((c) <= 0x0BAA)) ||				\
+      (((c) >= 0x0BAE) && ((c) <= 0x0BB5)) ||				\
+      (((c) >= 0x0BB7) && ((c) <= 0x0BB9)) ||				\
+      (((c) >= 0x0C05) && ((c) <= 0x0C0C)) ||				\
+      (((c) >= 0x0C0E) && ((c) <= 0x0C10)) ||				\
+      (((c) >= 0x0C12) && ((c) <= 0x0C28)) ||				\
+      (((c) >= 0x0C2A) && ((c) <= 0x0C33)) ||				\
+      (((c) >= 0x0C35) && ((c) <= 0x0C39)) ||				\
+      (((c) >= 0x0C60) && ((c) <= 0x0C61)) ||				\
+      (((c) >= 0x0C85) && ((c) <= 0x0C8C)) ||				\
+      (((c) >= 0x0C8E) && ((c) <= 0x0C90)) ||				\
+      (((c) >= 0x0C92) && ((c) <= 0x0CA8)) ||				\
+      (((c) >= 0x0CAA) && ((c) <= 0x0CB3)) ||				\
+      (((c) >= 0x0CB5) && ((c) <= 0x0CB9)) ||				\
+      ((c) == 0x0CDE) ||						\
+      (((c) >= 0x0CE0) && ((c) <= 0x0CE1)) ||				\
+      (((c) >= 0x0D05) && ((c) <= 0x0D0C)) ||				\
+      (((c) >= 0x0D0E) && ((c) <= 0x0D10)) ||				\
+      (((c) >= 0x0D12) && ((c) <= 0x0D28)) ||				\
+      (((c) >= 0x0D2A) && ((c) <= 0x0D39)) ||				\
+      (((c) >= 0x0D60) && ((c) <= 0x0D61)) ||				\
+      (((c) >= 0x0E01) && ((c) <= 0x0E2E)) ||				\
+      ((c) == 0x0E30) ||						\
+      (((c) >= 0x0E32) && ((c) <= 0x0E33)) ||				\
+      (((c) >= 0x0E40) && ((c) <= 0x0E45)) ||				\
+      (((c) >= 0x0E81) && ((c) <= 0x0E82)) ||				\
+      ((c) == 0x0E84) ||						\
+      (((c) >= 0x0E87) && ((c) <= 0x0E88)) ||				\
+      ((c) == 0x0E8A) ||						\
+      ((c) == 0x0E8D) ||						\
+      (((c) >= 0x0E94) && ((c) <= 0x0E97)) ||				\
+      (((c) >= 0x0E99) && ((c) <= 0x0E9F)) ||				\
+      (((c) >= 0x0EA1) && ((c) <= 0x0EA3)) ||				\
+      ((c) == 0x0EA5) ||						\
+      ((c) == 0x0EA7) ||						\
+      (((c) >= 0x0EAA) && ((c) <= 0x0EAB)) ||				\
+      (((c) >= 0x0EAD) && ((c) <= 0x0EAE)) ||				\
+      ((c) == 0x0EB0) ||						\
+      (((c) >= 0x0EB2) && ((c) <= 0x0EB3)) ||				\
+      ((c) == 0x0EBD) ||						\
+      (((c) >= 0x0EC0) && ((c) <= 0x0EC4)) ||				\
+      (((c) >= 0x0F40) && ((c) <= 0x0F47)) ||				\
+      (((c) >= 0x0F49) && ((c) <= 0x0F69)) ||				\
+      (((c) >= 0x10A0) && ((c) <= 0x10C5)) ||				\
+      (((c) >= 0x10D0) && ((c) <= 0x10F6)) ||				\
+      ((c) == 0x1100) ||						\
+      (((c) >= 0x1102) && ((c) <= 0x1103)) ||				\
+      (((c) >= 0x1105) && ((c) <= 0x1107)) ||				\
+      ((c) == 0x1109) ||						\
+      (((c) >= 0x110B) && ((c) <= 0x110C)) ||				\
+      (((c) >= 0x110E) && ((c) <= 0x1112)) ||				\
+      ((c) == 0x113C) ||						\
+      ((c) == 0x113E) ||						\
+      ((c) == 0x1140) ||						\
+      ((c) == 0x114C) ||						\
+      ((c) == 0x114E) ||						\
+      ((c) == 0x1150) ||						\
+      (((c) >= 0x1154) && ((c) <= 0x1155)) ||				\
+      ((c) == 0x1159) ||						\
+      (((c) >= 0x115F) && ((c) <= 0x1161)) ||				\
+      ((c) == 0x1163) ||						\
+      ((c) == 0x1165) ||						\
+      ((c) == 0x1167) ||						\
+      ((c) == 0x1169) ||						\
+      (((c) >= 0x116D) && ((c) <= 0x116E)) ||				\
+      (((c) >= 0x1172) && ((c) <= 0x1173)) ||				\
+      ((c) == 0x1175) ||						\
+      ((c) == 0x119E) ||						\
+      ((c) == 0x11A8) ||						\
+      ((c) == 0x11AB) ||						\
+      (((c) >= 0x11AE) && ((c) <= 0x11AF)) ||				\
+      (((c) >= 0x11B7) && ((c) <= 0x11B8)) ||				\
+      ((c) == 0x11BA) ||						\
+      (((c) >= 0x11BC) && ((c) <= 0x11C2)) ||				\
+      ((c) == 0x11EB) ||						\
+      ((c) == 0x11F0) ||						\
+      ((c) == 0x11F9) ||						\
+      (((c) >= 0x1E00) && ((c) <= 0x1E9B)) ||				\
+      (((c) >= 0x1EA0) && ((c) <= 0x1EF9)) ||				\
+      (((c) >= 0x1F00) && ((c) <= 0x1F15)) ||				\
+      (((c) >= 0x1F18) && ((c) <= 0x1F1D)) ||				\
+      (((c) >= 0x1F20) && ((c) <= 0x1F45)) ||				\
+      (((c) >= 0x1F48) && ((c) <= 0x1F4D)) ||				\
+      (((c) >= 0x1F50) && ((c) <= 0x1F57)) ||				\
+      ((c) == 0x1F59) ||						\
+      ((c) == 0x1F5B) ||						\
+      ((c) == 0x1F5D) ||						\
+      (((c) >= 0x1F5F) && ((c) <= 0x1F7D)) ||				\
+      (((c) >= 0x1F80) && ((c) <= 0x1FB4)) ||				\
+      (((c) >= 0x1FB6) && ((c) <= 0x1FBC)) ||				\
+      ((c) == 0x1FBE) ||						\
+      (((c) >= 0x1FC2) && ((c) <= 0x1FC4)) ||				\
+      (((c) >= 0x1FC6) && ((c) <= 0x1FCC)) ||				\
+      (((c) >= 0x1FD0) && ((c) <= 0x1FD3)) ||				\
+      (((c) >= 0x1FD6) && ((c) <= 0x1FDB)) ||				\
+      (((c) >= 0x1FE0) && ((c) <= 0x1FEC)) ||				\
+      (((c) >= 0x1FF2) && ((c) <= 0x1FF4)) ||				\
+      (((c) >= 0x1FF6) && ((c) <= 0x1FFC)) ||				\
+      ((c) == 0x2126) ||						\
+      (((c) >= 0x212A) && ((c) <= 0x212B)) ||				\
+      ((c) == 0x212E) ||						\
+      (((c) >= 0x2180) && ((c) <= 0x2182)) ||				\
+      (((c) >= 0x3041) && ((c) <= 0x3094)) ||				\
+      (((c) >= 0x30A1) && ((c) <= 0x30FA)) ||				\
+      (((c) >= 0x3105) && ((c) <= 0x312C)) ||				\
+      (((c) >= 0xAC00) && ((c) <= 0xD7A3)))
+
+/*
+ * [88] Digit ::= ... long list see REC ...
+ */
+#define IS_DIGIT(c) 							\
+     ((((c) >= 0x0030) && ((c) <= 0x0039)) ||				\
+      (((c) >= 0x0660) && ((c) <= 0x0669)) ||				\
+      (((c) >= 0x06F0) && ((c) <= 0x06F9)) ||				\
+      (((c) >= 0x0966) && ((c) <= 0x096F)) ||				\
+      (((c) >= 0x09E6) && ((c) <= 0x09EF)) ||				\
+      (((c) >= 0x0A66) && ((c) <= 0x0A6F)) ||				\
+      (((c) >= 0x0AE6) && ((c) <= 0x0AEF)) ||				\
+      (((c) >= 0x0B66) && ((c) <= 0x0B6F)) ||				\
+      (((c) >= 0x0BE7) && ((c) <= 0x0BEF)) ||				\
+      (((c) >= 0x0C66) && ((c) <= 0x0C6F)) ||				\
+      (((c) >= 0x0CE6) && ((c) <= 0x0CEF)) ||				\
+      (((c) >= 0x0D66) && ((c) <= 0x0D6F)) ||				\
+      (((c) >= 0x0E50) && ((c) <= 0x0E59)) ||				\
+      (((c) >= 0x0ED0) && ((c) <= 0x0ED9)) ||				\
+      (((c) >= 0x0F20) && ((c) <= 0x0F29)))
+
+/*
+ * [87] CombiningChar ::= ... long list see REC ...
+ */
+#define IS_COMBINING(c) 						\
+     ((((c) >= 0x0300) && ((c) <= 0x0345)) ||				\
+      (((c) >= 0x0360) && ((c) <= 0x0361)) ||				\
+      (((c) >= 0x0483) && ((c) <= 0x0486)) ||				\
+      (((c) >= 0x0591) && ((c) <= 0x05A1)) ||				\
+      (((c) >= 0x05A3) && ((c) <= 0x05B9)) ||				\
+      (((c) >= 0x05BB) && ((c) <= 0x05BD)) ||				\
+      ((c) == 0x05BF) ||						\
+      (((c) >= 0x05C1) && ((c) <= 0x05C2)) ||				\
+      ((c) == 0x05C4) ||						\
+      (((c) >= 0x064B) && ((c) <= 0x0652)) ||				\
+      ((c) == 0x0670) ||						\
+      (((c) >= 0x06D6) && ((c) <= 0x06DC)) ||				\
+      (((c) >= 0x06DD) && ((c) <= 0x06DF)) ||				\
+      (((c) >= 0x06E0) && ((c) <= 0x06E4)) ||				\
+      (((c) >= 0x06E7) && ((c) <= 0x06E8)) ||				\
+      (((c) >= 0x06EA) && ((c) <= 0x06ED)) ||				\
+      (((c) >= 0x0901) && ((c) <= 0x0903)) ||				\
+      ((c) == 0x093C) ||						\
+      (((c) >= 0x093E) && ((c) <= 0x094C)) ||				\
+      ((c) == 0x094D) ||						\
+      (((c) >= 0x0951) && ((c) <= 0x0954)) ||				\
+      (((c) >= 0x0962) && ((c) <= 0x0963)) ||				\
+      (((c) >= 0x0981) && ((c) <= 0x0983)) ||				\
+      ((c) == 0x09BC) ||						\
+      ((c) == 0x09BE) ||						\
+      ((c) == 0x09BF) ||						\
+      (((c) >= 0x09C0) && ((c) <= 0x09C4)) ||				\
+      (((c) >= 0x09C7) && ((c) <= 0x09C8)) ||				\
+      (((c) >= 0x09CB) && ((c) <= 0x09CD)) ||				\
+      ((c) == 0x09D7) ||						\
+      (((c) >= 0x09E2) && ((c) <= 0x09E3)) ||				\
+      ((c) == 0x0A02) ||						\
+      ((c) == 0x0A3C) ||						\
+      ((c) == 0x0A3E) ||						\
+      ((c) == 0x0A3F) ||						\
+      (((c) >= 0x0A40) && ((c) <= 0x0A42)) ||				\
+      (((c) >= 0x0A47) && ((c) <= 0x0A48)) ||				\
+      (((c) >= 0x0A4B) && ((c) <= 0x0A4D)) ||				\
+      (((c) >= 0x0A70) && ((c) <= 0x0A71)) ||				\
+      (((c) >= 0x0A81) && ((c) <= 0x0A83)) ||				\
+      ((c) == 0x0ABC) ||						\
+      (((c) >= 0x0ABE) && ((c) <= 0x0AC5)) ||				\
+      (((c) >= 0x0AC7) && ((c) <= 0x0AC9)) ||				\
+      (((c) >= 0x0ACB) && ((c) <= 0x0ACD)) ||				\
+      (((c) >= 0x0B01) && ((c) <= 0x0B03)) ||				\
+      ((c) == 0x0B3C) ||						\
+      (((c) >= 0x0B3E) && ((c) <= 0x0B43)) ||				\
+      (((c) >= 0x0B47) && ((c) <= 0x0B48)) ||				\
+      (((c) >= 0x0B4B) && ((c) <= 0x0B4D)) ||				\
+      (((c) >= 0x0B56) && ((c) <= 0x0B57)) ||				\
+      (((c) >= 0x0B82) && ((c) <= 0x0B83)) ||				\
+      (((c) >= 0x0BBE) && ((c) <= 0x0BC2)) ||				\
+      (((c) >= 0x0BC6) && ((c) <= 0x0BC8)) ||				\
+      (((c) >= 0x0BCA) && ((c) <= 0x0BCD)) ||				\
+      ((c) == 0x0BD7) ||						\
+      (((c) >= 0x0C01) && ((c) <= 0x0C03)) ||				\
+      (((c) >= 0x0C3E) && ((c) <= 0x0C44)) ||				\
+      (((c) >= 0x0C46) && ((c) <= 0x0C48)) ||				\
+      (((c) >= 0x0C4A) && ((c) <= 0x0C4D)) ||				\
+      (((c) >= 0x0C55) && ((c) <= 0x0C56)) ||				\
+      (((c) >= 0x0C82) && ((c) <= 0x0C83)) ||				\
+      (((c) >= 0x0CBE) && ((c) <= 0x0CC4)) ||				\
+      (((c) >= 0x0CC6) && ((c) <= 0x0CC8)) ||				\
+      (((c) >= 0x0CCA) && ((c) <= 0x0CCD)) ||				\
+      (((c) >= 0x0CD5) && ((c) <= 0x0CD6)) ||				\
+      (((c) >= 0x0D02) && ((c) <= 0x0D03)) ||				\
+      (((c) >= 0x0D3E) && ((c) <= 0x0D43)) ||				\
+      (((c) >= 0x0D46) && ((c) <= 0x0D48)) ||				\
+      (((c) >= 0x0D4A) && ((c) <= 0x0D4D)) ||				\
+      ((c) == 0x0D57) ||						\
+      ((c) == 0x0E31) ||						\
+      (((c) >= 0x0E34) && ((c) <= 0x0E3A)) ||				\
+      (((c) >= 0x0E47) && ((c) <= 0x0E4E)) ||				\
+      ((c) == 0x0EB1) ||						\
+      (((c) >= 0x0EB4) && ((c) <= 0x0EB9)) ||				\
+      (((c) >= 0x0EBB) && ((c) <= 0x0EBC)) ||				\
+      (((c) >= 0x0EC8) && ((c) <= 0x0ECD)) ||				\
+      (((c) >= 0x0F18) && ((c) <= 0x0F19)) ||				\
+      ((c) == 0x0F35) ||						\
+      ((c) == 0x0F37) ||						\
+      ((c) == 0x0F39) ||						\
+      ((c) == 0x0F3E) ||						\
+      ((c) == 0x0F3F) ||						\
+      (((c) >= 0x0F71) && ((c) <= 0x0F84)) ||				\
+      (((c) >= 0x0F86) && ((c) <= 0x0F8B)) ||				\
+      (((c) >= 0x0F90) && ((c) <= 0x0F95)) ||				\
+      ((c) == 0x0F97) ||						\
+      (((c) >= 0x0F99) && ((c) <= 0x0FAD)) ||				\
+      (((c) >= 0x0FB1) && ((c) <= 0x0FB7)) ||				\
+      ((c) == 0x0FB9) ||						\
+      (((c) >= 0x20D0) && ((c) <= 0x20DC)) ||				\
+      ((c) == 0x20E1) ||						\
+      (((c) >= 0x302A) && ((c) <= 0x302F)) ||				\
+      ((c) == 0x3099) ||						\
+      ((c) == 0x309A))
+
+/*
+ * [89] Extender ::= #x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 |
+ *                   #x0E46 | #x0EC6 | #x3005 | [#x3031-#x3035] |
+ *                   [#x309D-#x309E] | [#x30FC-#x30FE]
+ */
+#define IS_EXTENDER(c)							\
+    (((c) == 0xb7) || ((c) == 0x2d0) || ((c) == 0x2d1) ||		\
+     ((c) == 0x387) || ((c) == 0x640) || ((c) == 0xe46) ||		\
+     ((c) == 0xec6) || ((c) == 0x3005)					\
+     (((c) >= 0x3031) && ((c) <= 0x3035)) ||				\
+     (((c) >= 0x309b) && ((c) <= 0x309e)) ||				\
+     (((c) >= 0x30fc) && ((c) <= 0x30fe)))
+
+/*
+ * [86] Ideographic ::= [#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]
+ */
+#define IS_IDEOGRAPHIC(c)						\
+    ((((c) >= 0x4e00) && ((c) <= 0x9fa5)) ||				\
+     (((c) >= 0xf900) && ((c) <= 0xfa2d)) ||				\
+     (((c) >= 0x3021) && ((c) <= 0x3029)) ||				\
+      ((c) == 0x3007))
+
+/*
+ * [84] Letter ::= BaseChar | Ideographic 
+ */
+#define IS_LETTER(c) (IS_BASECHAR(c) || IS_IDEOGRAPHIC(c))
+
+#else
+/************************************************************************
+ *									*
+ * 8bits / ASCII version of the macros.					*
+ *									*
+ ************************************************************************/
+/*
+ * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
+ *                  | [#x10000-#x10FFFF]
+ * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
+ */
+#define IS_CHAR(c)							\
+    (((c) == 0x09) || ((c) == 0x0a) || ((c) == 0x0d) || ((c) >= 0x20) ||\
+     ((c) == 0xa))
+
+/*
+ * [85] BaseChar ::= ... long list see REC ...
+ */
+#define IS_BASECHAR(c)							\
+    ((((c) >= 0x41) && ((c) <= 0x5a)) ||				\
+     (((c) >= 0x61) && ((c) <= 0x7a)) ||				\
+     (((c) >= 0xaa) && ((c) <= 0x5b)) ||				\
+     (((c) >= 0xc0) && ((c) <= 0xd6)) ||				\
+     (((c) >= 0xd8) && ((c) <= 0xf6)) ||				\
+     (((c) >= 0xf8) && ((c) <= 0xff)) ||				\
+      ((c) == 0xba))
+
+/*
+ * [88] Digit ::= ... long list see REC ...
+ */
+#define IS_DIGIT(c) (((c) >= 0x30) && ((c) <= 0x39))
+
+/*
+ * [84] Letter ::= BaseChar | Ideographic 
+ */
+#define IS_LETTER(c) IS_BASECHAR(c)
+
+
+/*
+ * [87] CombiningChar ::= ... long list see REC ...
+ */
+#define IS_COMBINING(c) 0
+
+/*
+ * [89] Extender ::= #x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 |
+ *                   #x0E46 | #x0EC6 | #x3005 | [#x3031-#x3035] |
+ *                   [#x309D-#x309E] | [#x30FC-#x30FE]
+ */
+#define IS_EXTENDER(c) ((c) == 0xb7)
+
+#endif /* !UNICODE */
+
+/*
+ * Blank chars.
+ *
+ * [3] S ::= (#x20 | #x9 | #xD | #xA)+
+ */
+#define IS_BLANK(c) (((c) == 0x20) || ((c) == 0x09) || ((c) == 0xa) ||	\
+                     ((c) == 0x0D))
+
+/*
+ * [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
+ */
+#define IS_PUBIDCHAR(c)							\
+    (((c) == 0x20) || ((c) == 0x0D) || ((c) == 0x0A) ||			\
+     (((c) >= 'a') && ((c) <= 'z')) ||					\
+     (((c) >= 'A') && ((c) <= 'Z')) ||					\
+     (((c) >= '0') && ((c) <= '9')) ||					\
+     ((c) == '-') || ((c) == '\'') || ((c) == '(') || ((c) == ')') ||	\
+     ((c) == '+') || ((c) == ',') || ((c) == '.') || ((c) == '/') ||	\
+     ((c) == ':') || ((c) == '=') || ((c) == '?') || ((c) == ';') ||	\
+     ((c) == '!') || ((c) == '*') || ((c) == '#') || ((c) == '@') ||	\
+     ((c) == '$') || ((c) == '_') || ((c) == '%'))
+
+#define SKIP_EOL(p) 							\
+    if (*(p) == 0x13) { p++ ; if (*(p) == 0x10) p++; }			\
+    if (*(p) == 0x10) { p++ ; if (*(p) == 0x13) p++; }
+
+#define MOVETO_ENDTAG(p)						\
+    while (IS_CHAR(*p) && (*(p) != '>')) (p)++
+
+#define MOVETO_STARTTAG(p)						\
+    while (IS_CHAR(*p) && (*(p) != '<')) (p)++
+
+/************************************************************************
+ *									*
+ *		Commodity functions to handle CHARs			*
+ *									*
+ ************************************************************************/
+
+/*
+ * xmlStrndup : a strndup for array of CHAR's
+ */
+
+CHAR *xmlStrndup(const CHAR *cur, int len) {
+    CHAR *ret = malloc((len + 1) * sizeof(CHAR));
+
+    if (ret == NULL) {
+        fprintf(stderr, "malloc of %d byte failed\n",
+	        (len + 1) * sizeof(CHAR));
+        return(NULL);
+    }
+    memcpy(ret, cur, len * sizeof(CHAR));
+    ret[len] = 0;
+    return(ret);
+}
+
+/*
+ * xmlStrdup : a strdup for CHAR's
+ */
+
+CHAR *xmlStrdup(const CHAR *cur) {
+    const CHAR *p = cur;
+
+    while (IS_CHAR(*p)) p++;
+    return(xmlStrndup(cur, p - cur));
+}
+
+/*
+ * xmlCharStrndup : a strndup for char's to CHAR's
+ */
+
+CHAR *xmlCharStrndup(const char *cur, int len) {
+    int i;
+    CHAR *ret = malloc((len + 1) * sizeof(CHAR));
+
+    if (ret == NULL) {
+        fprintf(stderr, "malloc of %d byte failed\n",
+	        (len + 1) * sizeof(CHAR));
+        return(NULL);
+    }
+    for (i = 0;i < len;i++)
+        ret[i] = (CHAR) cur[i];
+    ret[len] = 0;
+    return(ret);
+}
+
+/*
+ * xmlCharStrdup : a strdup for char's to CHAR's
+ */
+
+CHAR *xmlCharStrdup(const char *cur) {
+    const char *p = cur;
+
+    while (*p != '\0') p++;
+    return(xmlCharStrndup(cur, p - cur));
+}
+
+/*
+ * xmlStrcmp : a strcmp for CHAR's
+ */
+
+int xmlStrcmp(const CHAR *str1, const CHAR *str2) {
+    register int tmp;
+
+    do {
+        tmp = *str1++ - *str2++;
+	if (tmp != 0) return(tmp);
+    } while ((*str1 != 0) && (*str2 != 0));
+    return (*str1 - *str2);
+}
+
+/*
+ * xmlStrncmp : a strncmp for CHAR's
+ */
+
+int xmlStrncmp(const CHAR *str1, const CHAR *str2, int len) {
+    register int tmp;
+
+    if (len <= 0) return(0);
+    do {
+        tmp = *str1++ - *str2++;
+	if (tmp != 0) return(tmp);
+	len--;
+        if (len <= 0) return(0);
+    } while ((*str1 != 0) && (*str2 != 0));
+    return (*str1 - *str2);
+}
+
+/*
+ * xmlStrchr : a strchr for CHAR's
+ */
+
+CHAR *xmlStrchr(const CHAR *str, CHAR val) {
+    while (*str != 0) {
+        if (*str == val) return((CHAR *) str);
+	str++;
+    }
+    return(NULL);
+}
+
+/*
+ * xmlStrlen : lenght of a CHAR's string
+ */
+
+int xmlStrlen(const CHAR *str) {
+    int len = 0;
+
+    if (str == NULL) return(0);
+    while (*str != 0) {
+	str++;
+	len++;
+    }
+    return(len);
+}
+
+/*
+ * xmlStrncat : a strncat for array of CHAR's
+ */
+
+CHAR *xmlStrncat(CHAR *cur, const CHAR *add, int len) {
+    int size;
+    CHAR *ret;
+
+    if ((add == NULL) || (len == 0))
+        return(cur);
+    if (cur == NULL)
+        return(xmlStrndup(add, len));
+
+    size = xmlStrlen(cur);
+    ret = realloc(cur, (size + len + 1) * sizeof(CHAR));
+    if (ret == NULL) {
+        fprintf(stderr, "xmlStrncat: realloc of %d byte failed\n",
+	        (size + len + 1) * sizeof(CHAR));
+        return(cur);
+    }
+    memcpy(&ret[size], add, len * sizeof(CHAR));
+    ret[size + len] = 0;
+    return(ret);
+}
+
+/*
+ * xmlStrcat : a strcat for CHAR's
+ */
+
+CHAR *xmlStrcat(CHAR *cur, const CHAR *add) {
+    const CHAR *p = add;
+
+    if (add == NULL) return(cur);
+    if (cur == NULL) 
+        return(xmlStrdup(add));
+
+    while (IS_CHAR(*p)) p++;
+    return(xmlStrncat(cur, add, p - add));
+}
+
+/************************************************************************
+ *									*
+ *		Commodity functions, cleanup needed ?			*
+ *									*
+ ************************************************************************/
+
+/*
+ * Is this a sequence of blank chars that one can ignore ?
+ */
+
+static int areBlanks(xmlParserCtxtPtr ctxt, const CHAR *str, int len) {
+    int i;
+    xmlNodePtr lastChild;
+
+    for (i = 0;i < len;i++)
+        if (!(IS_BLANK(str[i]))) return(0);
+
+    if (CUR != '<') return(0);
+    lastChild = xmlGetLastChild(ctxt->node);
+    if (lastChild == NULL) {
+        if (ctxt->node->content != NULL) return(0);
+    } else if (xmlNodeIsText(lastChild))
+        return(0);
+    return(1);
+}
+
+/*
+ * Handling of defined entities, when should we define a new input
+ * stream ? When do we just handle that as a set of chars ?
+ */
+
+void xmlHandleEntity(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
+    int len;
+
+    if (entity->content == NULL) {
+        xmlParserError(ctxt, "xmlHandleEntity %s: content == NULL\n",
+	               entity->name);
+        return;
+    }
+    len = xmlStrlen(entity->content);
+    if (len <= 2) goto handle_as_char;
+
+    /*
+     * Redefine its content as an input stream.
+     */
+    xmlNewEntityInputStream(ctxt, entity);
+    return;
+
+handle_as_char:
+    /*
+     * Just handle the content as a set of chars.
+     */
+    if (ctxt->sax != NULL)
+	ctxt->sax->characters(ctxt, entity->content, 0, len);
+
+}
+
+/*
+ * Forward definition for recusive behaviour.
+ */
+xmlNodePtr xmlParseElement(xmlParserCtxtPtr ctxt);
+CHAR *xmlParsePEReference(xmlParserCtxtPtr ctxt, int inLine);
+CHAR *xmlParseReference(xmlParserCtxtPtr ctxt, int inLine);
+
+/************************************************************************
+ *									*
+ *		Extra stuff for namespace support			*
+ *	Relates to http://www.w3.org/TR/WD-xml-names			*
+ *									*
+ ************************************************************************/
+
+/*
+ * xmlNamespaceParseNCName : parse an XML namespace name.
+ *
+ * [NS 3] NCName ::= (Letter | '_') (NCNameChar)*
+ *
+ * [NS 4] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
+ *                       CombiningChar | Extender
+ */
+
+CHAR *xmlNamespaceParseNCName(xmlParserCtxtPtr ctxt) {
+    const CHAR *q;
+    CHAR *ret = NULL;
+
+    if (!IS_LETTER(CUR) && (CUR != '_')) return(NULL);
+    q = NEXT;
+
+    while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
+           (CUR == '.') || (CUR == '-') ||
+	   (CUR == '_') ||
+	   (IS_COMBINING(CUR)) ||
+	   (IS_EXTENDER(CUR)))
+	NEXT;
+    
+    ret = xmlStrndup(q, CUR_PTR - q);
+
+    return(ret);
+}
+
+/*
+ * xmlNamespaceParseQName : parse an XML qualified name
+ *
+ * [NS 5] QName ::= (Prefix ':')? LocalPart
+ *
+ * [NS 6] Prefix ::= NCName
+ *
+ * [NS 7] LocalPart ::= NCName
+ */
+
+CHAR *xmlNamespaceParseQName(xmlParserCtxtPtr ctxt, CHAR **prefix) {
+    CHAR *ret = NULL;
+
+    *prefix = NULL;
+    ret = xmlNamespaceParseNCName(ctxt);
+    if (CUR == ':') {
+        *prefix = ret;
+	NEXT;
+	ret = xmlNamespaceParseNCName(ctxt);
+    }
+
+    return(ret);
+}
+
+/*
+ * xmlNamespaceParseNSDef : parse a namespace prefix declaration
+ *
+ * [NS 1] NSDef ::= PrefixDef Eq SystemLiteral
+ *
+ * [NS 2] PrefixDef ::= 'xmlns' (':' NCName)?
+ */
+
+CHAR *xmlNamespaceParseNSDef(xmlParserCtxtPtr ctxt) {
+    CHAR *name = NULL;
+
+    if ((CUR == 'x') && (NXT(1) == 'm') &&
+        (NXT(2) == 'l') && (NXT(3) == 'n') &&
+	(NXT(4) == 's')) {
+	SKIP(5);
+	if (CUR == ':') {
+	    NEXT;
+	    name = xmlNamespaceParseNCName(ctxt);
+	}
+    }
+    return(name);
+}
+
+/*
+ * [OLD] Parse and return a string between quotes or doublequotes
+ */
+CHAR *xmlParseQuotedString(xmlParserCtxtPtr ctxt) {
+    CHAR *ret = NULL;
+    const CHAR *q;
+
+    if (CUR == '"') {
+        NEXT;
+	q = CUR_PTR;
+	while (IS_CHAR(CUR) && (CUR != '"')) NEXT;
+	if (CUR != '"')
+	    xmlParserError(ctxt, "String not closed\"%.50s\n", q);
+        else {
+            ret = xmlStrndup(q, CUR_PTR - q);
+	    NEXT;
+	}
+    } else if (CUR == '\''){
+        NEXT;
+	q = CUR_PTR;
+	while (IS_CHAR(CUR) && (CUR != '\'')) NEXT;
+	if (CUR != '\'')
+	    xmlParserError(ctxt, "String not closed\"%.50s\n", q);
+        else {
+            ret = xmlStrndup(q, CUR_PTR - q);
+	    NEXT;
+	}
+    }
+    return(ret);
+}
+
+/*
+ * [OLD] xmlParseNamespace: parse specific PI '<?namespace ...' constructs.
+ *
+ * This is what the older xml-name Working Draft specified, a bunch of
+ * other stuff may still rely on it, so support is still here as
+ * if ot was declared on the root of the Tree:-(
+ */
+
+void xmlParseNamespace(xmlParserCtxtPtr ctxt) {
+    CHAR *href = NULL;
+    CHAR *prefix = NULL;
+    int garbage = 0;
+
+    /*
+     * We just skipped "namespace" or "xml:namespace"
+     */
+    SKIP_BLANKS;
+
+    while (IS_CHAR(CUR) && (CUR != '>')) {
+	/*
+	 * We can have "ns" or "prefix" attributes
+	 * Old encoding as 'href' or 'AS' attributes is still supported
+	 */
+	if ((CUR == 'n') && (NXT(1) == 's')) {
+	    garbage = 0;
+	    SKIP(2);
+	    SKIP_BLANKS;
+
+	    if (CUR != '=') continue;
+	    NEXT;
+	    SKIP_BLANKS;
+
+	    href = xmlParseQuotedString(ctxt);
+	    SKIP_BLANKS;
+	} else if ((CUR == 'h') && (NXT(1) == 'r') &&
+	    (NXT(2) == 'e') && (NXT(3) == 'f')) {
+	    garbage = 0;
+	    SKIP(4);
+	    SKIP_BLANKS;
+
+	    if (CUR != '=') continue;
+	    NEXT;
+	    SKIP_BLANKS;
+
+	    href = xmlParseQuotedString(ctxt);
+	    SKIP_BLANKS;
+	} else if ((CUR == 'p') && (NXT(1) == 'r') &&
+	           (NXT(2) == 'e') && (NXT(3) == 'f') &&
+	           (NXT(4) == 'i') && (NXT(5) == 'x')) {
+	    garbage = 0;
+	    SKIP(6);
+	    SKIP_BLANKS;
+
+	    if (CUR != '=') continue;
+	    NEXT;
+	    SKIP_BLANKS;
+
+	    prefix = xmlParseQuotedString(ctxt);
+	    SKIP_BLANKS;
+	} else if ((CUR == 'A') && (NXT(1) == 'S')) {
+	    garbage = 0;
+	    SKIP(2);
+	    SKIP_BLANKS;
+
+	    if (CUR != '=') continue;
+	    NEXT;
+	    SKIP_BLANKS;
+
+	    prefix = xmlParseQuotedString(ctxt);
+	    SKIP_BLANKS;
+	} else if ((CUR == '?') && (NXT(1) == '>')) {
+	    garbage = 0;
+	    CUR_PTR ++;
+	} else {
+            /*
+	     * Found garbage when parsing the namespace
+	     */
+	    if (!garbage)
+		xmlParserError(ctxt, "xmlParseNamespace found garbage\n");
+            NEXT;
+        }
+    }
+
+    MOVETO_ENDTAG(CUR_PTR);
+    NEXT;
+
+    /*
+     * Register the DTD.
+     */
+    if (href != NULL)
+        xmlNewGlobalNs(ctxt->doc, href, prefix);
+
+    if (prefix != NULL) free(prefix);
+    if (href != NULL) free(href);
+}
+
+/************************************************************************
+ *									*
+ *			The parser itself				*
+ *	Relates to http://www.w3.org/TR/REC-xml				*
+ *									*
+ ************************************************************************/
+
+/*
+ * xmlParseName : parse an XML name.
+ *
+ * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
+ *                  CombiningChar | Extender
+ *
+ * [5] Name ::= (Letter | '_' | ':') (NameChar)*
+ *
+ * [6] Names ::= Name (S Name)*
+ */
+
+CHAR *xmlParseName(xmlParserCtxtPtr ctxt) {
+    const CHAR *q;
+    CHAR *ret = NULL;
+
+    if (!IS_LETTER(CUR) && (CUR != '_') &&
+        (CUR != ':')) return(NULL);
+    q = NEXT;
+
+    while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
+           (CUR == '.') || (CUR == '-') ||
+	   (CUR == '_') || (CUR == ':') || 
+	   (IS_COMBINING(CUR)) ||
+	   (IS_EXTENDER(CUR)))
+	NEXT;
+    
+    ret = xmlStrndup(q, CUR_PTR - q);
+
+    return(ret);
+}
+
+/*
+ * xmlParseNmtoken : parse an XML Nmtoken.
+ *
+ * [7] Nmtoken ::= (NameChar)+
+ *
+ * [8] Nmtokens ::= Nmtoken (S Nmtoken)*
+ */
+
+CHAR *xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
+    const CHAR *q;
+    CHAR *ret = NULL;
+
+    q = NEXT;
+
+    while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
+           (CUR == '.') || (CUR == '-') ||
+	   (CUR == '_') || (CUR == ':') || 
+	   (IS_COMBINING(CUR)) ||
+	   (IS_EXTENDER(CUR)))
+	NEXT;
+    
+    ret = xmlStrndup(q, CUR_PTR - q);
+
+    return(ret);
+}
+
+/*
+ * xmlParseEntityValue : parse a value for ENTITY decl.
+ *
+ * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
+ *	               "'" ([^%&'] | PEReference | Reference)* "'"
+ */
+
+CHAR *xmlParseEntityValue(xmlParserCtxtPtr ctxt) {
+    CHAR *ret = NULL, *cur;
+    const CHAR *q;
+
+    if (CUR == '"') {
+        NEXT;
+
+	q = CUR_PTR;
+	while ((IS_CHAR(CUR)) && (CUR != '"')) {
+	    if (CUR == '%') {
+	        ret = xmlStrncat(ret, q, CUR_PTR - q);
+	        cur = xmlParsePEReference(ctxt, 1);
+		ret = xmlStrcat(ret, cur);
+		q = CUR_PTR;
+	    } else if (CUR == '&') {
+	        ret = xmlStrncat(ret, q, CUR_PTR - q);
+	        cur = xmlParseReference(ctxt, 1);
+		ret = xmlStrcat(ret, cur);
+		q = CUR_PTR;
+	    } else 
+	        NEXT;
+	}
+	if (!IS_CHAR(CUR)) {
+	    xmlParserError(ctxt, "Unfinished EntityValue\n");
+	} else {
+	    ret = xmlStrncat(ret, q, CUR_PTR - q);
+	    NEXT;
+        }
+    } else if (CUR == '\'') {
+        NEXT;
+	q = CUR_PTR;
+	while ((IS_CHAR(CUR)) && (CUR != '\'')) {
+	    if (CUR == '%') {
+	        ret = xmlStrncat(ret, q, CUR_PTR - q);
+	        cur = xmlParsePEReference(ctxt, 1);
+		ret = xmlStrcat(ret, cur);
+		q = CUR_PTR;
+	    } else if (CUR == '&') {
+	        ret = xmlStrncat(ret, q, CUR_PTR - q);
+	        cur = xmlParseReference(ctxt, 1);
+		ret = xmlStrcat(ret, cur);
+		q = CUR_PTR;
+	    } else 
+	        NEXT;
+	}
+	if (!IS_CHAR(CUR)) {
+	    xmlParserError(ctxt, "Unfinished EntityValue\n");
+	} else {
+	    ret = xmlStrncat(ret, q, CUR_PTR - q);
+	    NEXT;
+        }
+    } else {
+	xmlParserError(ctxt, "xmlParseEntityValue \" or ' expected\n");
+    }
+    
+    return(ret);
+}
+
+/*
+ * xmlParseAttValue : parse a value for an attribute
+ *
+ * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
+ *                   "'" ([^<&'] | Reference)* "'"
+ */
+
+CHAR *xmlParseAttValue(xmlParserCtxtPtr ctxt) {
+    CHAR *ret = NULL, *cur;
+    const CHAR *q;
+
+    if (CUR == '"') {
+        NEXT;
+
+	q = CUR_PTR;
+	while ((IS_CHAR(CUR)) && (CUR != '"')) {
+	    if (CUR == '&') {
+	        ret = xmlStrncat(ret, q, CUR_PTR - q);
+	        cur = xmlParseReference(ctxt, 1);
+		ret = xmlStrcat(ret, cur);
+		q = CUR_PTR;
+	    } else 
+	        NEXT;
+	}
+	if (!IS_CHAR(CUR)) {
+	    xmlParserError(ctxt, "Unfinished AttValue\n");
+	} else {
+	    ret = xmlStrncat(ret, q, CUR_PTR - q);
+	    NEXT;
+        }
+    } else if (CUR == '\'') {
+        NEXT;
+	q = CUR_PTR;
+	while ((IS_CHAR(CUR)) && (CUR != '\'')) {
+	    if (CUR == '&') {
+	        ret = xmlStrncat(ret, q, CUR_PTR - q);
+	        cur = xmlParseReference(ctxt, 1);
+		ret = xmlStrcat(ret, cur);
+		q = CUR_PTR;
+	    } else 
+	        NEXT;
+	}
+	if (!IS_CHAR(CUR)) {
+	    xmlParserError(ctxt, "Unfinished AttValue\n");
+	} else {
+	    ret = xmlStrncat(ret, q, CUR_PTR - q);
+	    NEXT;
+        }
+    } else {
+	xmlParserError(ctxt, "AttValue: \" or ' expected\n");
+    }
+    
+    return(ret);
+}
+
+/*
+ * xmlParseSystemLiteral : parse an XML Literal
+ *
+ * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
+ */
+
+CHAR *xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
+    const CHAR *q;
+    CHAR *ret = NULL;
+
+    if (CUR == '"') {
+        NEXT;
+	q = CUR_PTR;
+	while ((IS_CHAR(CUR)) && (CUR != '"'))
+	    NEXT;
+	if (!IS_CHAR(CUR)) {
+	    xmlParserError(ctxt, "Unfinished SystemLiteral\n");
+	} else {
+	    ret = xmlStrndup(q, CUR_PTR - q);
+	    NEXT;
+        }
+    } else if (CUR == '\'') {
+        NEXT;
+	q = CUR_PTR;
+	while ((IS_CHAR(CUR)) && (CUR != '\''))
+	    NEXT;
+	if (!IS_CHAR(CUR)) {
+	    xmlParserError(ctxt, "Unfinished SystemLiteral\n");
+	} else {
+	    ret = xmlStrndup(q, CUR_PTR - q);
+	    NEXT;
+        }
+    } else {
+	xmlParserError(ctxt, "SystemLiteral \" or ' expected\n");
+    }
+    
+    return(ret);
+}
+
+/*
+ * xmlParsePubidLiteral: parse an XML public literal
+ *
+ * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
+ */
+
+CHAR *xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
+    const CHAR *q;
+    CHAR *ret = NULL;
+    /*
+     * Name ::= (Letter | '_') (NameChar)*
+     */
+    if (CUR == '"') {
+        NEXT;
+	q = CUR_PTR;
+	while (IS_PUBIDCHAR(CUR)) NEXT;
+	if (CUR != '"') {
+	    xmlParserError(ctxt, "Unfinished PubidLiteral\n");
+	} else {
+	    ret = xmlStrndup(q, CUR_PTR - q);
+	    NEXT;
+	}
+    } else if (CUR == '\'') {
+        NEXT;
+	q = CUR_PTR;
+	while ((IS_LETTER(CUR)) && (CUR != '\''))
+	    NEXT;
+	if (!IS_LETTER(CUR)) {
+	    xmlParserError(ctxt, "Unfinished PubidLiteral\n");
+	} else {
+	    ret = xmlStrndup(q, CUR_PTR - q);
+	    NEXT;
+	}
+    } else {
+	xmlParserError(ctxt, "SystemLiteral \" or ' expected\n");
+    }
+    
+    return(ret);
+}
+
+/*
+ * xmlParseCharData: parse a CharData section.
+ *   if we are within a CDATA section ']]>' marks an end of section.
+ *
+ * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
+ */
+
+void xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
+    const CHAR *q;
+
+    q = CUR_PTR;
+    while ((IS_CHAR(CUR)) && (CUR != '<') &&
+           (CUR != '&')) {
+        NEXT;
+	if ((cdata) && (CUR == ']') && (NXT(1) == ']') &&
+	    (NXT(2) == '>')) break;
+    }
+    if (q == CUR_PTR) return;
+
+    /*
+     * Ok the segment [q CUR_PTR] is to be consumed as chars.
+     */
+    if (ctxt->sax != NULL) {
+	if (areBlanks(ctxt, q, CUR_PTR - q))
+	    ctxt->sax->ignorableWhitespace(ctxt, q, 0, CUR_PTR - q);
+	else
+	    ctxt->sax->characters(ctxt, q, 0, CUR_PTR - q);
+    }
+}
+
+/*
+ * xmlParseExternalID: Parse an External ID
+ *
+ * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
+ *                   | 'PUBLIC' S PubidLiteral S SystemLiteral
+ */
+
+CHAR *xmlParseExternalID(xmlParserCtxtPtr ctxt, CHAR **publicID) {
+    CHAR *URI = NULL;
+
+    if ((CUR == 'S') && (NXT(1) == 'Y') &&
+         (NXT(2) == 'S') && (NXT(3) == 'T') &&
+	 (NXT(4) == 'E') && (NXT(5) == 'M')) {
+        SKIP(6);
+        SKIP_BLANKS;
+	URI = xmlParseSystemLiteral(ctxt);
+	if (URI == NULL)
+	    xmlParserError(ctxt,
+	          "xmlParseExternalID: SYSTEM, no URI\n");
+    } else if ((CUR == 'P') && (NXT(1) == 'U') &&
+	       (NXT(2) == 'B') && (NXT(3) == 'L') &&
+	       (NXT(4) == 'I') && (NXT(5) == 'C')) {
+        SKIP(6);
+        SKIP_BLANKS;
+	*publicID = xmlParsePubidLiteral(ctxt);
+	if (*publicID == NULL)
+	    xmlParserError(ctxt, 
+	          "xmlParseExternalID: PUBLIC, no Public Identifier\n");
+        SKIP_BLANKS;
+	URI = xmlParseSystemLiteral(ctxt);
+	if (URI == NULL)
+	    xmlParserError(ctxt, 
+	           "xmlParseExternalID: PUBLIC, no URI\n");
+    }
+    return(URI);
+}
+
+/*
+ * Skip an XML (SGML) comment <!-- .... -->
+ *  This may or may not create a node (depending on the context)
+ *  The spec says that "For compatibility, the string "--" (double-hyphen)
+ *  must not occur within comments. "
+ *
+ * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
+ */
+xmlNodePtr xmlParseComment(xmlParserCtxtPtr ctxt, int create) {
+    xmlNodePtr ret = NULL;
+    const CHAR *q, *start;
+    const CHAR *r;
+    CHAR *val;
+
+    /*
+     * Check that there is a comment right here.
+     */
+    if ((CUR != '<') || (NXT(1) != '!') ||
+        (NXT(2) != '-') || (NXT(3) != '-')) return(NULL);
+
+    SKIP(4);
+    start = q = CUR_PTR;
+    NEXT;
+    r = CUR_PTR;
+    NEXT;
+    while (IS_CHAR(CUR) &&
+           ((CUR == ':') || (CUR != '>') ||
+	    (*r != '-') || (*q != '-'))) {
+	if ((*r == '-') && (*q == '-'))
+	    xmlParserError(ctxt,
+	       "Comment must not contain '--' (double-hyphen)`\n");
+        NEXT;r++;q++;
+    }
+    if (!IS_CHAR(CUR)) {
+	xmlParserError(ctxt, "Comment not terminated \n<!--%.50s\n", start);
+    } else {
+        NEXT;
+	if (create) {
+	    val = xmlStrndup(start, q - start);
+	    ret = xmlNewComment(val);
+	    free(val);
+	}
+    }
+    return(ret);
+}
+
+/*
+ * xmlParsePITarget: parse the name of a PI
+ *
+ * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
+ */
+
+CHAR *xmlParsePITarget(xmlParserCtxtPtr ctxt) {
+    CHAR *name;
+
+    name = xmlParseName(ctxt);
+    if ((name != NULL) && (name[3] == 0) &&
+        ((name[0] == 'x') || (name[0] == 'X')) &&
+        ((name[1] == 'm') || (name[1] == 'M')) &&
+        ((name[2] == 'l') || (name[2] == 'L'))) {
+	xmlParserError(ctxt, "xmlParsePItarget: invalid name prefix 'xml'\n");
+	return(NULL);
+    }
+    return(name);
+}
+
+/*
+ * xmlParsePI: parse an XML Processing Instruction.
+ *
+ * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
+ */
+
+void xmlParsePI(xmlParserCtxtPtr ctxt) {
+    CHAR *target;
+
+    if ((CUR == '<') && (NXT(1) == '?')) {
+	/*
+	 * this is a Processing Instruction.
+	 */
+	SKIP(2);
+
+	/*
+	 * Parse the target name and check for special support like
+	 * namespace.
+	 *
+	 * TODO : PI handling should be dynamically redefinable using an
+	 *        API. Only namespace should be in the code IMHO ...
+	 */
+        target = xmlParsePITarget(ctxt);
+	if (target != NULL) {
+	    /*
+	     * Support for the old Processing Instruction related to namespace.
+	     */
+	    if ((target[0] == 'n') && (target[1] == 'a') &&
+		(target[2] == 'm') && (target[3] == 'e') &&
+		(target[4] == 's') && (target[5] == 'p') &&
+		(target[6] == 'a') && (target[7] == 'c') &&
+		(target[8] == 'e')) {
+		xmlParseNamespace(ctxt);
+	    } else if ((target[0] == 'x') && (target[1] == 'm') &&
+		       (target[2] == 'l') && (target[3] == ':') &&
+		       (target[4] == 'n') && (target[5] == 'a') &&
+		       (target[6] == 'm') && (target[7] == 'e') &&
+		       (target[8] == 's') && (target[9] == 'p') &&
+		       (target[10] == 'a') && (target[11] == 'c') &&
+		       (target[12] == 'e')) {
+		xmlParseNamespace(ctxt);
+	    } else {
+	        const CHAR *q = CUR_PTR;
+
+		while (IS_CHAR(CUR) &&
+		       ((CUR != '?') || (NXT(1) != '>')))
+		    NEXT;
+		if (!IS_CHAR(CUR)) {
+		    xmlParserError(ctxt, "xmlParsePI: PI %s never end ...\n",
+		                   target);
+		} else {
+		    CHAR *data;
+
+		    data = xmlStrndup(CUR_PTR, CUR_PTR - q);
+		    SKIP(2);
+
+		    /*
+		     * SAX: PI detected.
+		     */
+		    if (ctxt->sax) 
+			ctxt->sax->processingInstruction(ctxt, target, data);
+		    /*
+		     * Unknown PI, ignore it !
+		     */
+		    else 
+			xmlParserWarning(ctxt,
+		           "xmlParsePI : skipping unknown PI %s\n",
+				         target);
+	            free(data);
+                }
+	    }
+	    free(target);
+	} else {
+	    xmlParserError(ctxt, "xmlParsePI : no target name\n");
+	    /********* Should we try to complete parsing the PI ???
+	    while (IS_CHAR(CUR) &&
+		   (CUR != '?') && (CUR != '>'))
+		NEXT;
+	    if (!IS_CHAR(CUR)) {
+		fprintf(stderr, "xmlParsePI: PI %s never end ...\n",
+			target);
+	    }
+	     ********************************************************/
+	}
+    }
+}
+
+/*
+ * xmlParseNotationDecl: parse a notation declaration
+ *
+ * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
+ *
+ * [83] PublicID ::= 'PUBLIC' S PubidLiteral
+ *
+ * NOTE: Actually [75] and [83] interract badly since [75] can generate
+ *       'PUBLIC' S PubidLiteral S SystemLiteral
+ *
+ * Hence there is actually 3 choices:
+ *     'PUBLIC' S PubidLiteral
+ *     'PUBLIC' S PubidLiteral S SystemLiteral
+ * and 'SYSTEM' S SystemLiteral
+ */
+
+void xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
+    CHAR *name;
+    
+    if ((CUR == '<') && (NXT(1) == '!') &&
+        (NXT(2) == 'N') && (NXT(3) == 'O') &&
+        (NXT(4) == 'T') && (NXT(5) == 'A') &&
+        (NXT(6) == 'T') && (NXT(7) == 'I') &&
+        (NXT(8) == 'O') && (NXT(9) == 'N') &&
+        (IS_BLANK(NXT(10)))) {
+	SKIP(10);
+        SKIP_BLANKS;
+
+        name = xmlParseName(ctxt);
+	if (name == NULL) {
+	    xmlParserError(ctxt,
+	        "xmlParseAttributeListDecl: no name for Element\n");
+	    return;
+	}
+	SKIP_BLANKS;
+	/*
+	 * TODO !!!
+	 */
+	while ((IS_CHAR(CUR)) && (CUR != '>'))
+	    NEXT;
+	free(name);
+    }
+}
+
+/*
+ * xmlParseEntityDecl: parse <!ENTITY declarations
+ *
+ * [70] EntityDecl ::= GEDecl | PEDecl
+ *
+ * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
+ *
+ * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
+ *
+ * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
+ *
+ * [74] PEDef ::= EntityValue | ExternalID
+ *
+ * [76] NDataDecl ::= S 'NDATA' S Name
+ */
+
+void xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
+    CHAR *name = NULL;
+    CHAR *value = NULL;
+    CHAR *URI = NULL, *literal = NULL;
+    CHAR *ndata = NULL;
+    int isParameter = 0;
+    
+    if ((CUR == '<') && (NXT(1) == '!') &&
+        (NXT(2) == 'E') && (NXT(3) == 'N') &&
+        (NXT(4) == 'T') && (NXT(5) == 'I') &&
+        (NXT(6) == 'T') && (NXT(7) == 'Y') &&
+        (IS_BLANK(NXT(8)))) {
+	SKIP(8);
+        SKIP_BLANKS;
+
+	if (CUR == '%') {
+	    NEXT;
+	    SKIP_BLANKS;
+	    isParameter = 1;
+	}
+
+        name = xmlParseName(ctxt);
+	if (name == NULL) {
+	    xmlParserError(ctxt, "xmlParseEntityDecl: no name\n");
+            return;
+	}
+        SKIP_BLANKS;
+
+	/*
+	 * TODO handle the various case of definitions...
+	 */
+	if (isParameter) {
+	    if ((CUR == '"') || (CUR == '\''))
+	        value = xmlParseEntityValue(ctxt);
+		if (value) {
+		    xmlAddDocEntity(ctxt->doc, name,
+		                    XML_INTERNAL_PARAMETER_ENTITY,
+				    NULL, NULL, value);
+		}
+	    else {
+	        URI = xmlParseExternalID(ctxt, &literal);
+		if (URI) {
+		    xmlAddDocEntity(ctxt->doc, name,
+		                    XML_EXTERNAL_PARAMETER_ENTITY,
+				    literal, URI, NULL);
+		}
+	    }
+	} else {
+	    if ((CUR == '"') || (CUR == '\'')) {
+	        value = xmlParseEntityValue(ctxt);
+		xmlAddDocEntity(ctxt->doc, name,
+				XML_INTERNAL_GENERAL_ENTITY,
+				NULL, NULL, value);
+	    } else {
+	        URI = xmlParseExternalID(ctxt, &literal);
+		SKIP_BLANKS;
+		if ((CUR == 'N') && (NXT(1) == 'D') &&
+		    (NXT(2) == 'A') && (NXT(3) == 'T') &&
+		    (NXT(4) == 'A')) {
+		    SKIP(5);
+		    SKIP_BLANKS;
+		    ndata = xmlParseName(ctxt);
+		    xmlAddDocEntity(ctxt->doc, name,
+				    XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
+				    literal, URI, ndata);
+		} else {
+		    xmlAddDocEntity(ctxt->doc, name,
+				    XML_EXTERNAL_GENERAL_PARSED_ENTITY,
+				    literal, URI, NULL);
+		}
+	    }
+	}
+	SKIP_BLANKS;
+	if (CUR != '>') {
+	    xmlParserError(ctxt, 
+	            "xmlParseEntityDecl: entity %s not terminated\n", name);
+	} else
+	    NEXT;
+	if (name != NULL) free(name);
+	if (value != NULL) free(value);
+	if (URI != NULL) free(URI);
+	if (literal != NULL) free(literal);
+	if (ndata != NULL) free(ndata);
+    }
+}
+
+/*
+ * xmlParseEnumeratedType: parse and Enumerated attribute type.
+ *
+ * [57] EnumeratedType ::= NotationType | Enumeration
+ *
+ * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
+ *
+ * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
+ */
+
+void xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, CHAR *name) {
+    /*
+     * TODO !!!
+     */
+    while ((IS_CHAR(CUR)) && (CUR != '>'))
+        NEXT;
+}
+
+/*
+ * xmlParseAttributeType: parse the Attribute list def for an element
+ *
+ * [54] AttType ::= StringType | TokenizedType | EnumeratedType
+ *
+ * [55] StringType ::= 'CDATA'
+ *
+ * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
+ *                        'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
+ */
+void xmlParseAttributeType(xmlParserCtxtPtr ctxt, CHAR *name) {
+    /* TODO !!! */
+    if ((CUR == 'C') && (NXT(1) == 'D') &&
+        (NXT(2) == 'A') && (NXT(3) == 'T') &&
+        (NXT(4) == 'A')) {
+	SKIP(5);
+     } else if ((CUR == 'I') && (NXT(1) == 'D')) {
+        SKIP(2);
+     } else if ((CUR == 'I') && (NXT(1) == 'D') &&
+        (NXT(2) == 'R') && (NXT(3) == 'E') &&
+        (NXT(4) == 'F')) {
+	SKIP(5);
+     } else if ((CUR == 'I') && (NXT(1) == 'D') &&
+        (NXT(2) == 'R') && (NXT(3) == 'E') &&
+        (NXT(4) == 'F') && (NXT(5) == 'S')) {
+	SKIP(6);
+     } else if ((CUR == 'E') && (NXT(1) == 'N') &&
+        (NXT(2) == 'T') && (NXT(3) == 'I') &&
+        (NXT(4) == 'T') && (NXT(5) == 'Y')) {
+	SKIP(6);
+     } else if ((CUR == 'E') && (NXT(1) == 'N') &&
+        (NXT(2) == 'T') && (NXT(3) == 'I') &&
+        (NXT(4) == 'T') && (NXT(5) == 'I') &&
+        (NXT(6) == 'E') && (NXT(7) == 'S')) {
+	SKIP(8);
+     } else if ((CUR == 'N') && (NXT(1) == 'M') &&
+        (NXT(2) == 'T') && (NXT(3) == 'O') &&
+        (NXT(4) == 'K') && (NXT(5) == 'E') &&
+        (NXT(6) == 'N')) {
+	SKIP(7);
+     } else if ((CUR == 'N') && (NXT(1) == 'M') &&
+        (NXT(2) == 'T') && (NXT(3) == 'O') &&
+        (NXT(4) == 'K') && (NXT(5) == 'E') &&
+        (NXT(6) == 'N') && (NXT(7) == 'S')) {
+     } else {
+        xmlParseEnumeratedType(ctxt, name);
+     }
+}
+
+/*
+ * xmlParseAttributeListDecl: parse the Attribute list def for an element
+ *
+ * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
+ *
+ * [53] AttDef ::= S Name S AttType S DefaultDecl
+ */
+void xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
+    CHAR *name;
+
+    /* TODO !!! */
+    if ((CUR == '<') && (NXT(1) == '!') &&
+        (NXT(2) == 'A') && (NXT(3) == 'T') &&
+        (NXT(4) == 'T') && (NXT(5) == 'L') &&
+        (NXT(6) == 'I') && (NXT(7) == 'S') &&
+        (NXT(8) == 'T') && (IS_BLANK(NXT(9)))) {
+	SKIP(9);
+        SKIP_BLANKS;
+        name = xmlParseName(ctxt);
+	if (name == NULL) {
+	    xmlParserError(ctxt, 
+	        "xmlParseAttributeListDecl: no name for Element\n");
+	    return;
+	}
+	SKIP_BLANKS;
+	while (CUR != '>') {
+	    const CHAR *check = CUR_PTR;
+
+	    xmlParseAttributeType(ctxt, name);
+	    SKIP_BLANKS;
+	    if (check == CUR_PTR) {
+	        xmlParserError(ctxt, 
+		    "xmlParseAttributeListDecl: detected error\n");
+		break;
+	    }
+	}
+	if (CUR == '>')
+	    NEXT;
+
+	free(name);
+    }
+}
+
+/*
+ * xmlParseElementContentDecl: parse the declaration for an Element content
+ *        either Mixed or Children, the cases EMPTY and ANY being handled
+ *        int xmlParseElementDecl.
+ * 
+ * [47] children ::= (choice | seq) ('?' | '*' | '+')?
+ *
+ * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
+ *
+ * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
+ *
+ * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
+ *
+ * or
+ *
+ * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
+ *                '(' S? '#PCDATA' S? ')'
+ */
+
+void xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, CHAR *name) {
+    /*
+     * TODO This has to be parsed correctly, currently we just skip until
+     *      we reach the first '>'.
+     * !!!
+     */
+    while ((IS_CHAR(CUR)) && (CUR != '>'))
+        NEXT;
+}
+
+/*
+ * xmlParseElementDecl: parse an Element declaration.
+ *
+ * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
+ *
+ * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
+ *
+ * TODO There is a check [ VC: Unique Element Type Declaration ]
+ */
+void xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
+    CHAR *name;
+
+    if ((CUR == '<') && (NXT(1) == '!') &&
+        (NXT(2) == 'E') && (NXT(3) == 'L') &&
+        (NXT(4) == 'E') && (NXT(5) == 'M') &&
+        (NXT(6) == 'E') && (NXT(7) == 'N') &&
+        (NXT(8) == 'T') && (IS_BLANK(NXT(9)))) {
+	SKIP(9);
+        SKIP_BLANKS;
+        name = xmlParseName(ctxt);
+	if (name == NULL) {
+	    xmlParserError(ctxt, "xmlParseElementDecl: no name for Element\n");
+	    return;
+	}
+        SKIP_BLANKS;
+	if ((CUR == 'E') && (NXT(1) == 'M') &&
+	    (NXT(2) == 'P') && (NXT(3) == 'T') &&
+	    (NXT(4) == 'Y')) {
+	    SKIP(5);
+	    /*
+	     * Element must always be empty.
+	     */
+	} else if ((CUR == 'A') && (NXT(1) == 'N') &&
+	           (NXT(2) == 'Y')) {
+	    SKIP(3);
+	    /*
+	     * Element is a generic container.
+	     */
+	} else {
+	    xmlParseElementContentDecl(ctxt, name);
+	}
+	SKIP_BLANKS;
+	if (CUR != '>') {
+	    xmlParserError(ctxt, 
+	          "xmlParseElementDecl: expected '>' at the end\n");
+	} else
+	    NEXT;
+    }
+}
+
+/*
+ * xmlParseMarkupDecl: parse Markup declarations
+ *
+ * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
+ *                     NotationDecl | PI | Comment
+ *
+ * TODO There is a check [ VC: Proper Declaration/PE Nesting ]
+ */
+void xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
+    xmlParseElementDecl(ctxt);
+    xmlParseAttributeListDecl(ctxt);
+    xmlParseEntityDecl(ctxt);
+    xmlParseNotationDecl(ctxt);
+    xmlParsePI(ctxt);
+    xmlParseComment(ctxt, 0);
+}
+
+/*
+ * xmlParseCharRef: parse Reference declarations
+ *
+ * [66] CharRef ::= '&#' [0-9]+ ';' |
+ *                  '&#x' [0-9a-fA-F]+ ';'
+ */
+CHAR *xmlParseCharRef(xmlParserCtxtPtr ctxt, int inLine) {
+    int val = 0;
+    CHAR buf[2];
+
+    if ((CUR == '&') && (NXT(1) == '#') &&
+        (NXT(2) == 'x')) {
+	SKIP(3);
+	while (CUR != ';') {
+	    if ((CUR >= '0') && (CUR <= '9')) 
+	        val = val * 16 + (CUR - '0');
+	    else if ((CUR >= 'a') && (CUR <= 'f'))
+	        val = val * 16 + (CUR - 'a') + 10;
+	    else if ((CUR >= 'A') && (CUR <= 'F'))
+	        val = val * 16 + (CUR - 'A') + 10;
+	    else {
+	        xmlParserError(ctxt, "xmlParseCharRef: invalid value\n");
+		val = 0;
+		break;
+	    }
+	}
+	if (CUR != ';')
+	    NEXT;
+    } else if  ((CUR == '&') && (NXT(1) == '#')) {
+	SKIP(2);
+	while (CUR != ';') {
+	    if ((CUR >= '0') && (CUR <= '9')) 
+	        val = val * 16 + (CUR - '0');
+	    else {
+	        xmlParserError(ctxt, "xmlParseCharRef: invalid value\n");
+		val = 0;
+		break;
+	    }
+	}
+	if (CUR != ';')
+	    NEXT;
+    } else {
+	xmlParserError(ctxt, "xmlParseCharRef: invalid value\n");
+    }
+    /*
+     * Check the value IS_CHAR ...
+     */
+    if (IS_CHAR(val)) {
+        buf[0] = (CHAR) val;
+	buf[1] = 0;
+	if (inLine)
+	    return(xmlStrndup(buf, 1));
+	else if (ctxt->sax != NULL)
+	    ctxt->sax->characters(ctxt, buf, 0, 1);
+    } else {
+	xmlParserError(ctxt, "xmlParseCharRef: invalid value");
+    }
+    return(NULL);
+}
+
+/*
+ * xmlParseEntityRef: parse ENTITY references declarations
+ *
+ * [68] EntityRef ::= '&' Name ';'
+ */
+CHAR *xmlParseEntityRef(xmlParserCtxtPtr ctxt, int inLine) {
+    CHAR *ret = NULL;
+    CHAR *name;
+    xmlEntityPtr entity;
+
+    if (CUR == '&') {
+        NEXT;
+        name = xmlParseName(ctxt);
+	if (name == NULL) {
+	    xmlParserError(ctxt, "xmlParseEntityRef: no name\n");
+	} else {
+	    if (CUR == ';') {
+	        NEXT;
+		entity = xmlGetDocEntity(ctxt->doc, name);
+		if (entity == NULL) {
+		    /* TODO !!! Create a reference ! */
+		    xmlParserWarning(ctxt,
+		         "xmlParseEntityRef: &%s; not found\n", name);
+		}
+		/*
+		 * If we can get the content, push the entity content
+		 * as the next input stream.
+		 */
+		else {
+		    switch (entity->type) {
+		        case XML_INTERNAL_PARAMETER_ENTITY:
+			case XML_EXTERNAL_PARAMETER_ENTITY:
+			    xmlParserError(ctxt,
+		"internal: xmlGetDtdEntity returned a general entity\n");
+		            break;
+			case XML_INTERNAL_GENERAL_ENTITY:
+			    if (inLine)
+			        ret = entity->content;
+			    else
+				xmlHandleEntity(ctxt, entity);
+			    break;
+			case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
+			case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
+			    xmlParserWarning(ctxt,
+	    "xmlParseEntityRef: external entity &%s; not supported\n",
+	                                     name);
+	                    break;
+			default:
+			    xmlParserError(ctxt, 
+		    "internal: xmlParseEntityRef: unknown entity type %d\n",
+			                   entity->type);
+		    }
+		}
+	    } else {
+		char cst[2] = { '&', 0 };
+
+		xmlParserError(ctxt, "xmlParseEntityRef: expecting ';'\n");
+		ret = xmlStrndup(cst, 1);
+		ret = xmlStrcat(ret, name);
+	    }
+	    free(name);
+	}
+    }
+    return(ret);
+}
+
+/*
+ * xmlParseReference: parse Reference declarations
+ *
+ * [67] Reference ::= EntityRef | CharRef
+ */
+CHAR *xmlParseReference(xmlParserCtxtPtr ctxt, int inLine) {
+    if ((CUR == '&') && (NXT(1) == '#')) {
+        return(xmlParseCharRef(ctxt, inLine));
+    } else if (CUR == '&') {
+        return(xmlParseEntityRef(ctxt, inLine));
+    }
+    return(NULL);
+}
+
+/*
+ * xmlParsePEReference: parse PEReference declarations
+ *
+ * [69] PEReference ::= '%' Name ';'
+ */
+CHAR *xmlParsePEReference(xmlParserCtxtPtr ctxt, int inLine) {
+    CHAR *ret = NULL;
+    CHAR *name;
+    xmlEntityPtr entity;
+
+    if (CUR == '%') {
+        NEXT;
+        name = xmlParseName(ctxt);
+	if (name == NULL) {
+	    xmlParserError(ctxt, "xmlParsePEReference: no name\n");
+	} else {
+	    if (CUR == ';') {
+	        NEXT;
+		entity = xmlGetDtdEntity(ctxt->doc, name);
+		if (entity == NULL) {
+		    xmlParserWarning(ctxt,
+		         "xmlParsePEReference: %%%s; not found\n");
+		}
+		/*
+		 * If we can get the content, push the entity content
+		 * as the next input stream.
+		 */
+		else {
+		    switch (entity->type) {
+		        case XML_INTERNAL_PARAMETER_ENTITY:
+			    if (inLine)
+			        ret = entity->content;
+			    else
+				xmlNewEntityInputStream(ctxt, entity);
+			    break;
+			case XML_EXTERNAL_PARAMETER_ENTITY:
+			    xmlParserWarning(ctxt,
+	    "xmlParsePEReference: external entity %%%s; not supported\n");
+	                    break;
+			case XML_INTERNAL_GENERAL_ENTITY:
+			case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
+			case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
+			    xmlParserError(ctxt,
+		"internal: xmlGetDtdEntity returned a general entity\n");
+		            break;
+			default:
+			    xmlParserError(ctxt, 
+		    "internal: xmlParsePEReference: unknown entity type %d\n",
+			                   entity->type);
+		    }
+		}
+	    } else {
+		char cst[2] = { '&', 0 };
+
+		xmlParserError(ctxt, "xmlParsePEReference: expecting ';'\n");
+		ret = xmlStrndup(cst, 1);
+		ret = xmlStrcat(ret, name);
+	    }
+	    free(name);
+	}
+    }
+    return(ret);
+}
+
+/*
+ * xmlParseDocTypeDecl : parse a DOCTYPE declaration
+ *
+ * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? 
+ *                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
+ */
+
+void xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
+    xmlDtdPtr dtd;
+    CHAR *name;
+    CHAR *ExternalID = NULL;
+    CHAR *URI = NULL;
+
+    /*
+     * We know that '<!DOCTYPE' has been detected.
+     */
+    SKIP(9);
+
+    SKIP_BLANKS;
+
+    /*
+     * Parse the DOCTYPE name.
+     */
+    name = xmlParseName(ctxt);
+    if (name == NULL) {
+	xmlParserError(ctxt, "xmlParseDocTypeDecl : no DOCTYPE name !\n");
+    }
+
+    SKIP_BLANKS;
+
+    /*
+     * Check for SystemID and ExternalID
+     */
+    URI = xmlParseExternalID(ctxt, &ExternalID);
+    SKIP_BLANKS;
+
+    dtd = xmlNewDtd(ctxt->doc, name, ExternalID, URI);
+
+    /*
+     * Is there any DTD definition ?
+     */
+    if (CUR == '[') {
+        NEXT;
+	/*
+	 * Parse the succession of Markup declarations and 
+	 * PEReferences.
+	 * Subsequence (markupdecl | PEReference | S)*
+	 */
+	while (CUR != ']') {
+	    const CHAR *check = CUR_PTR;
+
+	    SKIP_BLANKS;
+	    xmlParseMarkupDecl(ctxt);
+	    xmlParsePEReference(ctxt, 0);
+
+	    if (CUR_PTR == check) {
+		xmlParserError(ctxt, 
+		 "xmlParseDocTypeDecl: error detected in Markup declaration\n");
+		break;
+	    }
+	}
+	if (CUR == ']') NEXT;
+    }
+
+    /*
+     * We should be at the end of the DOCTYPE declaration.
+     */
+    if (CUR != '>') {
+	xmlParserError(ctxt, "DOCTYPE unproperly terminated\n");
+        /* We shouldn't try to resynchronize ... */
+    }
+    NEXT;
+
+    /*
+     * Cleanup, since we don't use all those identifiers
+     * TODO : the DOCTYPE if available should be stored !
+     */
+    if (URI != NULL) free(URI);
+    if (ExternalID != NULL) free(ExternalID);
+    if (name != NULL) free(name);
+}
+
+/*
+ * xmlParseAttribute: parse a start of tag.
+ *
+ * [41] Attribute ::= Name Eq AttValue
+ *
+ * [25] Eq ::= S? '=' S?
+ *
+ * With namespace:
+ *
+ * [NS 11] Attribute ::= QName Eq AttValue
+ *
+ * Also the case QName == xmlns:??? is handled independently as a namespace
+ * definition.
+ */
+
+void xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlNodePtr node) {
+    CHAR *name, *value = NULL;
+    CHAR *ns;
+
+    name = xmlNamespaceParseQName(ctxt, &ns);
+    if (name == NULL) {
+	xmlParserError(ctxt, "error parsing attribute name\n");
+        return;
+    }
+
+    /*
+     * read the value
+     */
+    SKIP_BLANKS;
+    if (CUR == '=') {
+        NEXT;
+	SKIP_BLANKS;
+	value = xmlParseAttValue(ctxt);
+    } else {
+	xmlParserError(ctxt, "Specification mandate value for attribute %s\n",
+	               name);
+    }
+
+    /*
+     * Check whether it's a namespace definition
+     */
+    if ((ns == NULL) &&
+        (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
+        (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
+	/* a default namespace definition */
+	xmlNewNs(node, value, NULL);
+	if (name != NULL) 
+	    free(name);
+	if (value != NULL)
+	    free(value);
+	return;
+    }
+    if ((ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
+        (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
+	/* a standard namespace definition */
+	xmlNewNs(node, value, name);
+	if (name != NULL) 
+	    free(name);
+	if (value != NULL)
+	    free(value);
+	return;
+    }
+
+    /*
+     * Add the attribute to the node.
+     */
+    if (name != NULL) {
+	xmlNewProp(node, name, value);
+        free(name);
+    }
+    if (value != NULL)
+      free(value);
+}
+
+/*
+ * xmlParseStartTag: parse a start of tag either for rule element or
+ *      EmptyElement. In both case we don't parse the tag closing chars.
+ *
+ * [40] STag ::= '<' Name (S Attribute)* S? '>'
+ *
+ * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
+ *
+ * With namespace:
+ *
+ * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
+ *
+ * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
+ */
+
+xmlNodePtr xmlParseStartTag(xmlParserCtxtPtr ctxt) {
+    CHAR *namespace, *name;
+    xmlNsPtr ns = NULL;
+    xmlNodePtr ret = NULL;
+
+    if (CUR != '<') return(NULL);
+    NEXT;
+
+    name = xmlNamespaceParseQName(ctxt, &namespace);
+
+    /*
+     * Note : the namespace resolution is deferred until the end of the
+     *        attributes parsing, since local namespace can be defined as
+     *        an attribute at this level.
+     */
+    ret = xmlNewNode(ns, name, NULL);
+
+    /*
+     * Now parse the attributes, it ends up with the ending
+     *
+     * (S Attribute)* S?
+     */
+    SKIP_BLANKS;
+    while ((IS_CHAR(CUR)) &&
+           (CUR != '>') && 
+	   ((CUR != '/') || (NXT(1) != '>'))) {
+	const CHAR *q = CUR_PTR;
+
+	xmlParseAttribute(ctxt, ret);
+	SKIP_BLANKS;
+
+        if (q == CUR_PTR) {
+	    xmlParserError(ctxt, 
+	         "xmlParseStartTag: problem parsing attributes\n");
+	    break;
+	}
+    }
+
+    /*
+     * Search the namespace
+     */
+    ns = xmlSearchNs(ctxt->doc, ret, namespace);
+    if (ns == NULL) /* ret still doesn't have a parent yet ! */
+	ns = xmlSearchNs(ctxt->doc, ctxt->node, namespace);
+    xmlSetNs(ret, ns);
+    if (namespace != NULL)
+	free(namespace);
+
+    /*
+     * We are parsing a new node.
+     */
+    nodePush(ctxt, ret);
+
+    /*
+     * SAX: Start of Element !
+     */
+    if (ctxt->sax != NULL)
+        ctxt->sax->startElement(ctxt, name);
+
+    return(ret);
+}
+
+/*
+ * xmlParseEndTag: parse an end of tag
+ *
+ * [42] ETag ::= '</' Name S? '>'
+ *
+ * With namespace
+ *
+ * [9] ETag ::= '</' QName S? '>'
+ */
+
+void xmlParseEndTag(xmlParserCtxtPtr ctxt, xmlNsPtr *nsPtr, CHAR **tagPtr) {
+    CHAR *namespace, *name;
+    xmlNsPtr ns = NULL;
+
+    *nsPtr = NULL;
+    *tagPtr = NULL;
+
+    if ((CUR != '<') || (NXT(1) != '/')) {
+	xmlParserError(ctxt, "xmlParseEndTag: '</' not found\n");
+	return;
+    }
+    SKIP(2);
+
+    name = xmlNamespaceParseQName(ctxt, &namespace);
+
+    /*
+     * Search the namespace
+     */
+    ns = xmlSearchNs(ctxt->doc, ctxt->node, namespace);
+    if (namespace != NULL)
+	free(namespace);
+
+    *nsPtr = ns;
+    *tagPtr = name;
+
+    /*
+     * We should definitely be at the ending "S? '>'" part
+     */
+    SKIP_BLANKS;
+    if ((!IS_CHAR(CUR)) || (CUR != '>')) {
+	xmlParserError(ctxt, "End tag : expected '>'\n");
+    } else
+	NEXT;
+
+    return;
+}
+
+/*
+ * xmlParseCDSect: escaped pure raw content.
+ *
+ * [18] CDSect ::= CDStart CData CDEnd
+ *
+ * [19] CDStart ::= '<![CDATA['
+ *
+ * [20] Data ::= (Char* - (Char* ']]>' Char*))
+ *
+ * [21] CDEnd ::= ']]>'
+ */
+void xmlParseCDSect(xmlParserCtxtPtr ctxt) {
+    const CHAR *r, *s, *base;
+
+    if ((CUR == '<') && (NXT(1) == '!') &&
+	(NXT(2) == '[') && (NXT(3) == 'C') &&
+	(NXT(4) == 'D') && (NXT(5) == 'A') &&
+	(NXT(6) == 'T') && (NXT(7) == 'A') &&
+	(NXT(8) == '[')) {
+	SKIP(9);
+    } else
+        return;
+    base = CUR_PTR;
+    if (!IS_CHAR(CUR)) {
+	xmlParserError(ctxt, "CData section not finished\n%.50s\n", base);
+        return;
+    }
+    r = NEXT;
+    if (!IS_CHAR(CUR)) {
+	xmlParserError(ctxt, "CData section not finished\n%.50s\n", base);
+        return;
+    }
+    s = NEXT;
+    while (IS_CHAR(CUR) &&
+           ((*r != ']') || (*s != ']') || (CUR != '>'))) {
+        r++;s++;NEXT;
+    }
+    if (!IS_CHAR(CUR)) {
+	xmlParserError(ctxt, "CData section not finished\n%.50s\n", base);
+        return;
+    }
+
+    /*
+     * Ok the segment [base CUR_PTR] is to be consumed as chars.
+     */
+    if (ctxt->sax != NULL) {
+	if (areBlanks(ctxt, base, CUR_PTR - base))
+	    ctxt->sax->ignorableWhitespace(ctxt, base, 0, CUR_PTR - base);
+	else
+	    ctxt->sax->characters(ctxt, base, 0, CUR_PTR - base);
+    }
+}
+
+/*
+ * xmlParseContent: a content is
+ * (element | PCData | Reference | CDSect | PI | Comment)
+ *
+ * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
+ */
+
+void xmlParseContent(xmlParserCtxtPtr ctxt) {
+    xmlNodePtr ret = NULL;
+
+    while ((CUR != '<') || (NXT(1) != '/')) {
+	const CHAR *test = CUR_PTR;
+        ret = NULL;
+
+	/*
+	 * First case : a Processing Instruction.
+	 */
+	if ((CUR == '<') && (NXT(1) == '?')) {
+	    xmlParsePI(ctxt);
+	}
+	/*
+	 * Second case : a CDSection
+	 */
+	else if ((CUR == '<') && (NXT(1) == '!') &&
+	    (NXT(2) == '[') && (NXT(3) == 'C') &&
+	    (NXT(4) == 'D') && (NXT(5) == 'A') &&
+	    (NXT(6) == 'T') && (NXT(7) == 'A') &&
+	    (NXT(8) == '[')) {
+	    xmlParseCDSect(ctxt);
+	}
+	/*
+	 * Third case :  a comment
+	 */
+	else if ((CUR == '<') && (NXT(1) == '!') &&
+		 (NXT(2) == '-') && (NXT(3) == '-')) {
+	    ret = xmlParseComment(ctxt, 1);
+	}
+	/*
+	 * Fourth case :  a sub-element.
+	 */
+	else if (CUR == '<') {
+	    ret = xmlParseElement(ctxt);
+	}
+	/*
+	 * Fifth case : a reference.
+	 */
+	else if (CUR == '&') {
+	    xmlParseReference(ctxt, 0);
+	}
+	/*
+	 * Last case, text. Note that References are handled directly.
+	 */
+	else {
+	    xmlParseCharData(ctxt, 0);
+	}
+
+	/*
+	 * Pop-up of finished entities.
+	 */
+	while ((CUR == 0) && (ctxt->inputNr > 1)) xmlPopInput(ctxt);
+
+	if (test == CUR_PTR) {
+	    xmlParserError(ctxt, "detected an error in element content\n");
+            break;
+	}
+    }
+}
+
+/*
+ * xmlParseElement: parse an XML element
+ *
+ * [39] element ::= EmptyElemTag | STag content ETag
+ *
+ * [41] Attribute ::= Name Eq AttValue
+ */
+
+
+xmlNodePtr xmlParseElement(xmlParserCtxtPtr ctxt) {
+    xmlNodePtr ret;
+    const CHAR *openTag = CUR_PTR;
+    xmlParserNodeInfo node_info;
+    CHAR *endTag;
+    xmlNsPtr endNs;
+
+    /* Capture start position */
+    node_info.begin_pos = CUR_PTR - ctxt->input->base;
+    node_info.begin_line = ctxt->input->line;
+
+    ret = xmlParseStartTag(ctxt);
+    if (ret == NULL) {
+        return(NULL);
+    }
+
+    /*
+     * Check for an Empty Element.
+     */
+    if ((CUR == '/') && (NXT(1) == '>')) {
+        SKIP(2);
+	if (ctxt->sax != NULL)
+	    ctxt->sax->endElement(ctxt, ret->name);
+
+	/*
+	 * end of parsing of this node.
+	 */
+	nodePop(ctxt);
+
+	return(ret);
+    }
+    if (CUR == '>') NEXT;
+    else {
+	xmlParserError(ctxt, "Couldn't find end of Start Tag\n%.30s\n",openTag);
+
+	/*
+	 * end of parsing of this node.
+	 */
+	nodePop(ctxt);
+
+	return(NULL);
+    }
+
+    /*
+     * Parse the content of the element:
+     */
+    xmlParseContent(ctxt);
+    if (!IS_CHAR(CUR)) {
+	xmlParserError(ctxt, "Premature end of data in tag %.30s\n%.30s\n",
+	               openTag);
+
+	/*
+	 * end of parsing of this node.
+	 */
+	nodePop(ctxt);
+
+	return(NULL);
+    }
+
+    /*
+     * parse the end of tag: '</' should be here.
+     */
+    xmlParseEndTag(ctxt, &endNs, &endTag);
+
+    /*
+     * Check that the Name in the ETag is the same as in the STag.
+     */
+    if (endNs != ret->ns) {
+	xmlParserError(ctxt, 
+	    "Start and End tags don't use the same namespace\n%.30s\n%.30s\n",
+	               openTag, endTag);
+    }
+    if (endTag == NULL ) {
+	xmlParserError(ctxt, "The End tag has no name\n%.30s\n", openTag);
+    } else if (xmlStrcmp(ret->name, endTag)) {
+	xmlParserError(ctxt, 
+	    "Start and End tags don't use the same name\n%.30s\n%.30s\n",
+	               openTag, endTag);
+    }
+    /*
+     * SAX: End of Tag
+     */
+    else if (ctxt->sax != NULL)
+        ctxt->sax->endElement(ctxt, endTag);
+
+    if (endTag != NULL)
+	free(endTag);
+
+    /* Capture end position and add node */
+    if ( ret != NULL && ctxt->record_info ) {
+      node_info.end_pos = CUR_PTR - ctxt->input->base;
+      node_info.end_line = ctxt->input->line;
+      node_info.node = ret;
+      xmlParserAddNodeInfo(ctxt, &node_info);
+    }
+
+    /*
+     * end of parsing of this node.
+     */
+    nodePop(ctxt);
+
+    return(ret);
+}
+
+/*
+ * xmlParseVersionNum: parse the XML version value.
+ *
+ * [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+
+ */
+CHAR *xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
+    const CHAR *q = CUR_PTR;
+    CHAR *ret;
+
+    while (IS_CHAR(CUR) &&
+           (((CUR >= 'a') && (CUR <= 'z')) ||
+            ((CUR >= 'A') && (CUR <= 'Z')) ||
+            ((CUR >= '0') && (CUR <= '9')) ||
+            (CUR == '_') || (CUR == '.') ||
+	    (CUR == ':') || (CUR == '-'))) NEXT;
+    ret = xmlStrndup(q, CUR_PTR - q);
+    return(ret);
+}
+
+/*
+ * xmlParseVersionInfo: parse the XML version.
+ *
+ * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
+ * 
+ * [25] Eq ::= S? '=' S?
+ */
+
+CHAR *xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
+    CHAR *version = NULL;
+    const CHAR *q;
+
+    if ((CUR == 'v') && (NXT(1) == 'e') &&
+        (NXT(2) == 'r') && (NXT(3) == 's') &&
+	(NXT(4) == 'i') && (NXT(5) == 'o') &&
+	(NXT(6) == 'n')) {
+	SKIP(7);
+	SKIP_BLANKS;
+	if (CUR != '=') {
+	    xmlParserError(ctxt, "xmlParseVersionInfo : expected '='\n");
+	    return(NULL);
+        }
+	NEXT;
+	SKIP_BLANKS;
+	if (CUR == '"') {
+	    NEXT;
+	    q = CUR_PTR;
+	    version = xmlParseVersionNum(ctxt);
+	    if (CUR != '"')
+		xmlParserError(ctxt, "String not closed\n%.50s\n", q);
+	    else
+	        NEXT;
+	} else if (CUR == '\''){
+	    NEXT;
+	    q = CUR_PTR;
+	    version = xmlParseVersionNum(ctxt);
+	    if (CUR != '\'')
+		xmlParserError(ctxt, "String not closed\n%.50s\n", q);
+	    else
+	        NEXT;
+	} else {
+	    xmlParserError(ctxt, "xmlParseVersionInfo : expected ' or \"\n");
+	}
+    }
+    return(version);
+}
+
+/*
+ * xmlParseEncName: parse the XML encoding name
+ *
+ * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
+ */
+CHAR *xmlParseEncName(xmlParserCtxtPtr ctxt) {
+    const CHAR *q = CUR_PTR;
+    CHAR *ret = NULL;
+
+    if (((CUR >= 'a') && (CUR <= 'z')) ||
+        ((CUR >= 'A') && (CUR <= 'Z'))) {
+	NEXT;
+	while (IS_CHAR(CUR) &&
+	       (((CUR >= 'a') && (CUR <= 'z')) ||
+		((CUR >= 'A') && (CUR <= 'Z')) ||
+		((CUR >= '0') && (CUR <= '9')) ||
+		(CUR == '-'))) NEXT;
+	ret = xmlStrndup(q, CUR_PTR - q);
+    } else {
+	xmlParserError(ctxt, "Invalid XML encoding name\n");
+    }
+    return(ret);
+}
+
+/*
+ * xmlParseEncodingDecl: parse the XML encoding declaration
+ *
+ * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'")
+ */
+
+CHAR *xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
+    CHAR *encoding = NULL;
+    const CHAR *q;
+
+    SKIP_BLANKS;
+    if ((CUR == 'e') && (NXT(1) == 'n') &&
+        (NXT(2) == 'c') && (NXT(3) == 'o') &&
+	(NXT(4) == 'd') && (NXT(5) == 'i') &&
+	(NXT(6) == 'n') && (NXT(7) == 'g')) {
+	SKIP(8);
+	SKIP_BLANKS;
+	if (CUR != '=') {
+	    xmlParserError(ctxt, "xmlParseEncodingDecl : expected '='\n");
+	    return(NULL);
+        }
+	NEXT;
+	SKIP_BLANKS;
+	if (CUR == '"') {
+	    NEXT;
+	    q = CUR_PTR;
+	    encoding = xmlParseEncName(ctxt);
+	    if (CUR != '"')
+		xmlParserError(ctxt, "String not closed\n%.50s\n", q);
+	    else
+	        NEXT;
+	} else if (CUR == '\''){
+	    NEXT;
+	    q = CUR_PTR;
+	    encoding = xmlParseEncName(ctxt);
+	    if (CUR != '\'')
+		xmlParserError(ctxt, "String not closed\n%.50s\n", q);
+	    else
+	        NEXT;
+	} else if (CUR == '"'){
+	    xmlParserError(ctxt, "xmlParseEncodingDecl : expected ' or \"\n");
+	}
+    }
+    return(encoding);
+}
+
+/*
+ * xmlParseSDDecl: parse the XML standalone declaration
+ *
+ * [32] SDDecl ::= S 'standalone' Eq
+ *                 (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"')) 
+ */
+
+int xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
+    int standalone = -1;
+
+    SKIP_BLANKS;
+    if ((CUR == 's') && (NXT(1) == 't') &&
+        (NXT(2) == 'a') && (NXT(3) == 'n') &&
+	(NXT(4) == 'd') && (NXT(5) == 'a') &&
+	(NXT(6) == 'l') && (NXT(7) == 'o') &&
+	(NXT(8) == 'n') && (NXT(9) == 'e')) {
+	SKIP(10);
+	if (CUR != '=') {
+	    xmlParserError(ctxt, "XML standalone declaration : expected '='\n");
+	    return(standalone);
+        }
+	NEXT;
+	SKIP_BLANKS;
+        if (CUR == '\''){
+	    NEXT;
+	    if ((CUR == 'n') && (NXT(1) == 'o')) {
+	        standalone = 0;
+                SKIP(2);
+	    } else if ((CUR == 'y') && (NXT(1) == 'e') &&
+	               (NXT(2) == 's')) {
+	        standalone = 1;
+		SKIP(3);
+            } else {
+		xmlParserError(ctxt, "standalone accepts only 'yes' or 'no'\n");
+	    }
+	    if (CUR != '\'')
+		xmlParserError(ctxt, "String not closed\n");
+	    else
+	        NEXT;
+	} else if (CUR == '"'){
+	    NEXT;
+	    if ((CUR == 'n') && (NXT(1) == 'o')) {
+	        standalone = 0;
+		SKIP(2);
+	    } else if ((CUR == 'y') && (NXT(1) == 'e') &&
+	               (NXT(2) == 's')) {
+	        standalone = 1;
+                SKIP(3);
+            } else {
+		xmlParserError(ctxt, "standalone accepts only 'yes' or 'no'\n");
+	    }
+	    if (CUR != '"')
+		xmlParserError(ctxt, "String not closed\n");
+	    else
+	        NEXT;
+	} else {
+            xmlParserError(ctxt, "Standalone value not found\n");
+        }
+    }
+    return(standalone);
+}
+
+/*
+ * xmlParseXMLDecl: parse an XML declaration header
+ *
+ * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
+ */
+
+void xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
+    CHAR *version;
+
+    /*
+     * We know that '<?xml' is here.
+     */
+    SKIP(5);
+
+    SKIP_BLANKS;
+
+    /*
+     * We should have the VersionInfo here.
+     */
+    version = xmlParseVersionInfo(ctxt);
+    if (version == NULL)
+	version = xmlCharStrdup(XML_DEFAULT_VERSION);
+    ctxt->doc = xmlNewDoc(version);
+    free(version);
+
+    /*
+     * We may have the encoding declaration
+     */
+    ctxt->doc->encoding = xmlParseEncodingDecl(ctxt);
+
+    /*
+     * We may have the standalone status.
+     */
+    ctxt->doc->standalone = xmlParseSDDecl(ctxt);
+
+    SKIP_BLANKS;
+    if ((CUR == '?') && (NXT(1) == '>')) {
+        SKIP(2);
+    } else if (CUR == '>') {
+        /* Deprecated old WD ... */
+	xmlParserError(ctxt, "XML declaration must end-up with '?>'\n");
+	NEXT;
+    } else {
+	xmlParserError(ctxt, "parsing XML declaration: '?>' expected\n");
+	MOVETO_ENDTAG(CUR_PTR);
+	NEXT;
+    }
+}
+
+/*
+ * xmlParseMisc: parse an XML Misc* optionnal field.
+ * Misc*
+ *
+ * [27] Misc ::= Comment | PI |  S
+ */
+
+void xmlParseMisc(xmlParserCtxtPtr ctxt) {
+    while (((CUR == '<') && (NXT(1) == '?')) ||
+           ((CUR == '<') && (NXT(1) == '!') &&
+	    (NXT(2) == '-') && (NXT(3) == '-')) ||
+           IS_BLANK(CUR)) {
+        if ((CUR == '<') && (NXT(1) == '?')) {
+	    xmlParsePI(ctxt);
+	} else if (IS_BLANK(CUR)) {
+	    NEXT;
+	} else
+	    xmlParseComment(ctxt, 0);
+    }
+}
+
+/*
+ * xmlParseDocument : parse an XML document and build a tree.
+ *
+ * [1] document ::= prolog element Misc*
+ *
+ * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
+ */
+
+int xmlParseDocument(xmlParserCtxtPtr ctxt) {
+    xmlDefaultSAXHandlerInit();
+
+    /*
+     * SAX: beginning of the document processing.
+     */
+    if (ctxt->sax) 
+        ctxt->sax->setDocumentLocator(ctxt, &xmlDefaultSAXLocator);
+    if (ctxt->sax)
+        ctxt->sax->startDocument(ctxt);
+
+    /*
+     * We should check for encoding here and plug-in some
+     * conversion code TODO !!!!
+     */
+
+    /*
+     * Wipe out everything which is before the first '<'
+     */
+    SKIP_BLANKS;
+
+    /*
+     * Check for the XMLDecl in the Prolog.
+     */
+    if ((CUR == '<') && (NXT(1) == '?') &&
+        (NXT(2) == 'x') && (NXT(3) == 'm') &&
+	(NXT(4) == 'l')) {
+	xmlParseXMLDecl(ctxt);
+	/* SKIP_EOL(cur); */
+	SKIP_BLANKS;
+    } else if ((CUR == '<') && (NXT(1) == '?') &&
+        (NXT(2) == 'X') && (NXT(3) == 'M') &&
+	(NXT(4) == 'L')) {
+	/*
+	 * The first drafts were using <?XML and the final W3C REC
+	 * now use <?xml ...
+	 */
+	xmlParseXMLDecl(ctxt);
+	/* SKIP_EOL(cur); */
+	SKIP_BLANKS;
+    } else {
+	CHAR *version;
+
+	version = xmlCharStrdup(XML_DEFAULT_VERSION);
+	ctxt->doc = xmlNewDoc(version);
+	free(version);
+    }
+
+    /*
+     * The Misc part of the Prolog
+     */
+    xmlParseMisc(ctxt);
+
+    /*
+     * Then possibly doc type declaration(s) and more Misc
+     * (doctypedecl Misc*)?
+     */
+    if ((CUR == '<') && (NXT(1) == '!') &&
+	(NXT(2) == 'D') && (NXT(3) == 'O') &&
+	(NXT(4) == 'C') && (NXT(5) == 'T') &&
+	(NXT(6) == 'Y') && (NXT(7) == 'P') &&
+	(NXT(8) == 'E')) {
+	xmlParseDocTypeDecl(ctxt);
+	xmlParseMisc(ctxt);
+    }
+
+    /*
+     * Time to start parsing the tree itself
+     */
+    ctxt->doc->root = xmlParseElement(ctxt);
+
+    /*
+     * The Misc part at the end
+     */
+    xmlParseMisc(ctxt);
+
+    /*
+     * SAX: end of the document processing.
+     */
+    if (ctxt->sax) 
+        ctxt->sax->endDocument(ctxt);
+    return(0);
+}
+
+/*
+ * xmlParseDoc : parse an XML in-memory document and build a tree.
+ */
+
+xmlDocPtr xmlParseDoc(CHAR *cur) {
+    xmlDocPtr ret;
+    xmlParserCtxtPtr ctxt;
+    xmlParserInputPtr input;
+
+    if (cur == NULL) return(NULL);
+
+    ctxt = (xmlParserCtxtPtr) malloc(sizeof(xmlParserCtxt));
+    if (ctxt == NULL) {
+        perror("malloc");
+	return(NULL);
+    }
+    xmlInitParserCtxt(ctxt);
+    input = (xmlParserInputPtr) malloc(sizeof(xmlParserInput));
+    if (input == NULL) {
+        perror("malloc");
+	free(ctxt);
+	return(NULL);
+    }
+
+    input->filename = NULL;
+    input->line = 1;
+    input->col = 1;
+    input->base = cur;
+    input->cur = cur;
+
+    inputPush(ctxt, input);
+
+
+    xmlParseDocument(ctxt);
+    ret = ctxt->doc;
+    free(ctxt);
+    
+    return(ret);
+}
+
+/*
+ * xmlParseFile : parse an XML file and build a tree.
+ */
+
+xmlDocPtr xmlParseFile(const char *filename) {
+    xmlDocPtr ret;
+#ifdef HAVE_ZLIB_H
+    gzFile input;
+#else
+    int input;
+#endif
+    int res;
+    struct stat buf;
+    char *buffer;
+    xmlParserCtxtPtr ctxt;
+    xmlParserInputPtr inputStream;
+
+    res = stat(filename, &buf);
+    if (res < 0) return(NULL);
+
+#ifdef HAVE_ZLIB_H
+retry_bigger:
+    buffer = malloc((buf.st_size * 20) + 100);
+#else
+    buffer = malloc(buf.st_size + 100);
+#endif
+    if (buffer == NULL) {
+	perror("malloc");
+        return(NULL);
+    }
+
+    memset(buffer, 0, sizeof(buffer));
+#ifdef HAVE_ZLIB_H
+    input = gzopen (filename, "r");
+    if (input == NULL) {
+        fprintf (stderr, "Cannot read file %s :\n", filename);
+	perror ("gzopen failed");
+	return(NULL);
+    }
+#else
+    input = open (filename, O_RDONLY);
+    if (input < 0) {
+        fprintf (stderr, "Cannot read file %s :\n", filename);
+	perror ("open failed");
+	return(NULL);
+    }
+#endif
+#ifdef HAVE_ZLIB_H
+    res = gzread(input, buffer, 20 * buf.st_size);
+#else
+    res = read(input, buffer, buf.st_size);
+#endif
+    if (res < 0) {
+        fprintf (stderr, "Cannot read file %s :\n", filename);
+#ifdef HAVE_ZLIB_H
+	perror ("gzread failed");
+#else
+	perror ("read failed");
+#endif
+	return(NULL);
+    }
+#ifdef HAVE_ZLIB_H
+    gzclose(input);
+    if (res >= 20 * buf.st_size) {
+        free(buffer);
+	buf.st_size *= 2;
+	goto retry_bigger;
+    }
+    buf.st_size = res;
+#else
+    close(input);
+#endif
+
+    buffer[buf.st_size] = '\0';
+
+    ctxt = (xmlParserCtxtPtr) malloc(sizeof(xmlParserCtxt));
+    if (ctxt == NULL) {
+        perror("malloc");
+	return(NULL);
+    }
+    xmlInitParserCtxt(ctxt);
+    inputStream = (xmlParserInputPtr) malloc(sizeof(xmlParserInput));
+    if (inputStream == NULL) {
+        perror("malloc");
+	free(ctxt);
+	return(NULL);
+    }
+
+    inputStream->filename = strdup(filename);
+    inputStream->line = 1;
+    inputStream->col = 1;
+
+    /*
+     * TODO : plug some encoding conversion routines here. !!!
+     */
+    inputStream->base = buffer;
+    inputStream->cur = buffer;
+
+    inputPush(ctxt, inputStream);
+
+    xmlParseDocument(ctxt);
+
+    ret = ctxt->doc;
+    free(buffer);
+    free(ctxt);
+    
+    return(ret);
+}
+
+
+/*
+ * xmlParseMemory : parse an XML memory block and build a tree.
+ */
+xmlDocPtr xmlParseMemory(char *buffer, int size) {
+    xmlDocPtr ret;
+    xmlParserCtxtPtr ctxt;
+    xmlParserInputPtr input;
+
+    buffer[size - 1] = '\0';
+
+    ctxt = (xmlParserCtxtPtr) malloc(sizeof(xmlParserCtxt));
+    if (ctxt == NULL) {
+        perror("malloc");
+	return(NULL);
+    }
+    xmlInitParserCtxt(ctxt);
+    input = (xmlParserInputPtr) malloc(sizeof(xmlParserInput));
+    if (input == NULL) {
+        perror("malloc");
+	free(ctxt);
+	return(NULL);
+    }
+
+    input->filename = NULL;
+    input->line = 1;
+    input->col = 1;
+
+    /*
+     * TODO : plug some encoding conversion routines here. !!!
+     */
+    input->base = buffer;
+    input->cur = buffer;
+
+    inputPush(ctxt, input);
+
+    xmlParseDocument(ctxt);
+
+    ret = ctxt->doc;
+    free(ctxt);
+    
+    return(ret);
+}
+
+
+/* Initialize parser context */
+void xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
+{
+  /* Allocate the Input stack */
+  ctxt->inputTab = (xmlParserInputPtr *) malloc(5 * sizeof(xmlParserInputPtr));
+  ctxt->inputNr = 0;
+  ctxt->inputMax = 5;
+  ctxt->input = NULL;
+
+  /* Allocate the Node stack */
+  ctxt->nodeTab = (xmlNodePtr *) malloc(10 * sizeof(xmlNodePtr));
+  ctxt->nodeNr = 0;
+  ctxt->nodeMax = 10;
+  ctxt->node = NULL;
+
+  ctxt->sax = &xmlDefaultSAXHandler;
+  ctxt->doc = NULL;
+  ctxt->record_info = 0;
+  xmlInitNodeInfoSeq(&ctxt->node_seq);
+}
+
+
+/*
+ * Clear (release owned resources) and reinitialize context
+ */
+void xmlClearParserCtxt(xmlParserCtxtPtr ctxt)
+{
+  xmlClearNodeInfoSeq(&ctxt->node_seq);
+  xmlInitParserCtxt(ctxt);
+}
+
+
+/*
+ * Setup the parser context to parse a new buffer; Clears any prior
+ * contents from the parser context. The buffer parameter must not be
+ * NULL, but the filename parameter can be
+ */
+void xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const CHAR* buffer,
+                             const char* filename)
+{
+  xmlParserInputPtr input;
+
+  input = (xmlParserInputPtr) malloc(sizeof(xmlParserInput));
+  if (input == NULL) {
+      perror("malloc");
+      free(ctxt);
+      exit(1);
+  }
+
+  xmlClearParserCtxt(ctxt);
+  if (input->filename != NULL)
+      input->filename = strdup(filename);
+  else
+      input->filename = NULL;
+  input->line = 1;
+  input->col = 1;
+  input->base = buffer;
+  input->cur = buffer;
+
+  inputPush(ctxt, input);
+}
+
+
+/*
+ * xmlParserFindNodeInfo : Find the parser node info struct for a given node
+ */
+const xmlParserNodeInfo* xmlParserFindNodeInfo(const xmlParserCtxt* ctx,
+                                               const xmlNode* node)
+{
+  unsigned long pos;
+
+  /* Find position where node should be at */
+  pos = xmlParserFindNodeInfoIndex(&ctx->node_seq, node);
+  if ( ctx->node_seq.buffer[pos].node == node )
+    return &ctx->node_seq.buffer[pos];
+  else
+    return NULL;
+}
+
+
+/*
+ * xmlInitNodeInfoSeq -- Initialize (set to initial state) node info sequence
+ */
+void xmlInitNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
+{
+  seq->length = 0;
+  seq->maximum = 0;
+  seq->buffer = NULL;
+}
+
+/*
+ * xmlClearNodeInfoSeq -- Clear (release memory and reinitialize) node
+ *   info sequence
+ */
+void xmlClearNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
+{
+  if ( seq->buffer != NULL )
+    free(seq->buffer);
+  xmlInitNodeInfoSeq(seq);
+}
+
+
+/*
+ * xmlParserFindNodeInfoIndex : Find the index that the info record for
+ *   the given node is or should be at in a sorted sequence
+ */
+unsigned long xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeq* seq,
+                                         const xmlNode* node)
+{
+  unsigned long upper, lower, middle;
+  int found = 0;
+
+  /* Do a binary search for the key */
+  lower = 1;
+  upper = seq->length;
+  middle = 0;
+  while ( lower <= upper && !found) {
+    middle = lower + (upper - lower) / 2;
+    if ( node == seq->buffer[middle - 1].node )
+      found = 1;
+    else if ( node < seq->buffer[middle - 1].node )
+      upper = middle - 1;
+    else
+      lower = middle + 1;
+  }
+
+  /* Return position */
+  if ( middle == 0 || seq->buffer[middle - 1].node < node )
+    return middle;
+  else 
+    return middle - 1;
+}
+
+
+/*
+ * xmlParserAddNodeInfo : Insert node info record into sorted sequence
+ */
+void xmlParserAddNodeInfo(xmlParserCtxtPtr ctx, 
+                          const xmlParserNodeInfo* info)
+{
+  unsigned long pos;
+  static unsigned int block_size = 5;
+
+  /* Find pos and check to see if node is already in the sequence */
+  pos = xmlParserFindNodeInfoIndex(&ctx->node_seq, info->node);
+  if ( pos < ctx->node_seq.length
+       && ctx->node_seq.buffer[pos].node == info->node ) {
+    ctx->node_seq.buffer[pos] = *info;
+  }
+
+  /* Otherwise, we need to add new node to buffer */
+  else {
+    /* Expand buffer by 5 if needed */
+    if ( ctx->node_seq.length + 1 > ctx->node_seq.maximum ) {
+      xmlParserNodeInfo* tmp_buffer;
+      unsigned int byte_size = (sizeof(*ctx->node_seq.buffer)
+                                *(ctx->node_seq.maximum + block_size));
+
+      if ( ctx->node_seq.buffer == NULL )
+        tmp_buffer = (xmlParserNodeInfo*)malloc(byte_size);
+      else 
+        tmp_buffer = (xmlParserNodeInfo*)realloc(ctx->node_seq.buffer, byte_size);
+
+      if ( tmp_buffer == NULL ) {
+        xmlParserError(ctx, "Out of memory");
+        return;
+      }
+      ctx->node_seq.buffer = tmp_buffer;
+      ctx->node_seq.maximum += block_size;
+    }
+
+    /* If position is not at end, move elements out of the way */
+    if ( pos != ctx->node_seq.length ) {
+      unsigned long i;
+
+      for ( i = ctx->node_seq.length; i > pos; i-- )
+        ctx->node_seq.buffer[i] = ctx->node_seq.buffer[i - 1];
+    }
+  
+    /* Copy element and increase length */
+    ctx->node_seq.buffer[pos] = *info;
+    ctx->node_seq.length++;
+  }   
+}
diff --git a/parser.h b/parser.h
new file mode 100644
index 0000000..a25e70a
--- /dev/null
+++ b/parser.h
@@ -0,0 +1,168 @@
+/*
+ * parser.h : constants and stuff related to the XML parser.
+ *
+ * See Copyright for the status of this software.
+ *
+ * $Id$
+ */
+
+#ifndef __XML_PARSER_H__
+#define __XML_PARSER_H__
+
+#include "tree.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Constants.
+ */
+#define XML_DEFAULT_VERSION	"1.0"
+
+typedef struct xmlParserInput {
+    const char *filename;             /* The file analyzed, if any */
+    const CHAR *base;                 /* Base of the array to parse */
+    const CHAR *cur;                  /* Current char being parsed */
+    int line;                         /* Current line */
+    int col;                          /* Current column */
+} xmlParserInput, *xmlParserInputPtr;
+
+typedef struct xmlParserNodeInfo {
+  const struct xmlNode* node;
+  /* Position & line # that text that created the node begins & ends on */
+  unsigned long begin_pos;
+  unsigned long begin_line;
+  unsigned long end_pos;
+  unsigned long end_line;
+} xmlParserNodeInfo;
+
+typedef struct xmlParserNodeInfoSeq {
+  unsigned long maximum;
+  unsigned long length;
+  xmlParserNodeInfo* buffer;
+} xmlParserNodeInfoSeq, *xmlParserNodeInfoSeqPtr;
+
+typedef struct xmlParserCtxt {
+    struct xmlSAXHandler *sax;        /* The SAX handler */
+    xmlDocPtr doc;                    /* the document being built */
+
+    /* Input stream stack */
+    xmlParserInputPtr  input;         /* Current input stream */
+    int                inputNr;       /* Number of current input streams */
+    int                inputMax;      /* Max number of input streams */
+    xmlParserInputPtr *inputTab;      /* stack of inputs */
+
+    /* Node analysis stack */
+    xmlNodePtr         node;          /* Current parsed Node */
+    int                nodeNr;        /* Depth of the parsing stack */
+    int                nodeMax;       /* Max depth of the parsing stack */
+    xmlNodePtr        *nodeTab;       /* array of nodes */
+
+    int record_info;                  /* Whether node info should be kept */
+    xmlParserNodeInfoSeq node_seq;    /* info about each node parsed */
+} xmlParserCtxt, *xmlParserCtxtPtr;
+
+/*
+ * a SAX Locator.
+ */
+
+typedef struct xmlSAXLocator {
+    const CHAR *(*getPublicId)(xmlParserCtxtPtr ctxt);
+    const CHAR *(*getSystemId)(xmlParserCtxtPtr ctxt);
+    int (*getLineNumber)(xmlParserCtxtPtr ctxt);
+    int (*getColumnNumber)(xmlParserCtxtPtr ctxt);
+} xmlSAXLocator, *xmlSAXLocatorPtr;
+
+/*
+ * a SAX Exception.
+ */
+
+typedef xmlParserInputPtr (*resolveEntitySAXFunc) (xmlParserCtxtPtr ctxt,
+			    const CHAR *publicId, const CHAR *systemId);
+typedef void (*notationDeclSAXFunc)(xmlParserCtxtPtr ctxt, const CHAR *name,
+			    const CHAR *publicId, const CHAR *systemId);
+typedef void (*unparsedEntityDeclSAXFunc)(xmlParserCtxtPtr ctxt,
+                            const CHAR *name, const CHAR *publicId,
+			    const CHAR *systemId, const CHAR *notationName);
+typedef void (*setDocumentLocatorSAXFunc) (xmlParserCtxtPtr ctxt,
+                            xmlSAXLocatorPtr loc);
+typedef void (*startDocumentSAXFunc) (xmlParserCtxtPtr ctxt);
+typedef void (*endDocumentSAXFunc) (xmlParserCtxtPtr ctxt);
+typedef void (*startElementSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *name);
+typedef void (*endElementSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *name);
+typedef void (*charactersSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *ch,
+		            int start, int len);
+typedef void (*ignorableWhitespaceSAXFunc) (xmlParserCtxtPtr ctxt,
+			    const CHAR *ch, int start, int len);
+typedef void (*processingInstructionSAXFunc) (xmlParserCtxtPtr ctxt,
+                            const CHAR *target, const CHAR *data);
+typedef void (*warningSAXFunc) (xmlParserCtxtPtr ctxt, const char *msg, ...);
+typedef void (*errorSAXFunc) (xmlParserCtxtPtr ctxt, const char *msg, ...);
+typedef void (*fatalErrorSAXFunc) (xmlParserCtxtPtr ctxt, const char *msg, ...);
+
+typedef struct xmlSAXHandler {
+    resolveEntitySAXFunc resolveEntity;
+    notationDeclSAXFunc notationDecl;
+    unparsedEntityDeclSAXFunc unparsedEntityDecl;
+    setDocumentLocatorSAXFunc setDocumentLocator;
+    startDocumentSAXFunc startDocument;
+    endDocumentSAXFunc endDocument;
+    startElementSAXFunc startElement;
+    endElementSAXFunc endElement;
+    charactersSAXFunc characters;
+    ignorableWhitespaceSAXFunc ignorableWhitespace;
+    processingInstructionSAXFunc processingInstruction;
+    warningSAXFunc warning;
+    errorSAXFunc error;
+    fatalErrorSAXFunc fatalError;
+} xmlSAXHandler, *xmlSAXHandlerPtr;
+
+/*
+ * Global variables: just the SAX interface tables we are looking for full
+ *      reentrancy of the code !
+ */
+xmlSAXLocator xmlDefaultSAXLocator;
+xmlSAXHandler xmlDefaultSAXHandler;
+
+/*
+ * Interfaces
+ */
+extern int xmlParseDocument(xmlParserCtxtPtr ctxt);
+extern xmlDocPtr xmlParseDoc(CHAR *cur);
+extern xmlDocPtr xmlParseMemory(char *buffer, int size);
+extern xmlDocPtr xmlParseFile(const char *filename);
+extern CHAR *xmlStrdup(const CHAR *input);
+extern CHAR *xmlStrndup(const CHAR *input, int n);
+extern CHAR *xmlStrchr(const CHAR *str, CHAR val);
+extern int xmlStrcmp(const CHAR *str1, const CHAR *str2);
+extern int xmlStrncmp(const CHAR *str1, const CHAR *str2, int len);
+extern int xmlStrlen(const CHAR *str);
+extern CHAR *xmlStrcat(CHAR *cur, const CHAR *add);
+extern CHAR *xmlStrncat(CHAR *cur, const CHAR *add, int len);
+
+extern void xmlInitParserCtxt(xmlParserCtxtPtr ctx);
+extern void xmlClearParserCtxt(xmlParserCtxtPtr ctx);
+extern void xmlSetupParserForBuffer(xmlParserCtxtPtr ctx, const CHAR* buffer,
+                                    const char* filename);
+
+extern void xmlParserError(xmlParserCtxtPtr ctxt, const char *msg, ...);
+
+extern const xmlParserNodeInfo* xmlParserFindNodeInfo(const xmlParserCtxt* c,
+                                                      const xmlNode* node);
+extern void xmlInitNodeInfoSeq(xmlParserNodeInfoSeqPtr seq);
+extern void xmlClearNodeInfoSeq(xmlParserNodeInfoSeqPtr seq);
+unsigned long xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeq* seq,
+                                         const xmlNode* node);
+extern void xmlParserAddNodeInfo(xmlParserCtxtPtr ctx,
+                                 const xmlParserNodeInfo* info);
+
+extern void xmlParserWarning(xmlParserCtxtPtr ctxt, const char *msg, ...);
+extern void xmlParserError(xmlParserCtxtPtr ctxt, const char *msg, ...);
+extern void xmlDefaultSAXHandlerInit(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_PARSER_H__ */
+
diff --git a/result/dav1 b/result/dav1
index 942f5ee..515463f 100644
--- a/result/dav1
+++ b/result/dav1
@@ -1,10 +1,5 @@
-
-
-------- test/dav1 -----------
 <?xml version="1.0"?>
-<?xml:namespace ns="http://www.foo.bar/boxschema" prefix="R"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:multistatus>
+<D:multistatus xmlns:D="http://www.ietf.org/standards/dav/" xmlns:R="http://www.foo.bar/boxschema">
   <D:response>
     <D:prop>
       <R:bigbox>
diff --git a/result/dav10 b/result/dav10
index eca7ad6..4b00da4 100644
--- a/result/dav10
+++ b/result/dav10
@@ -1,8 +1,4 @@
-
-
-------- test/dav10 -----------
 <?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:owner>
+<D:owner xmlns:D="http://www.ietf.org/standards/dav/">
   <D:href>http://www.ics.uci.edu/~ejw/contact.html</D:href>
 </D:owner>
diff --git a/result/dav11 b/result/dav11
index 9c7816e..a8e9c6f 100644
--- a/result/dav11
+++ b/result/dav11
@@ -1,9 +1,5 @@
-
-
-------- test/dav11 -----------
 <?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:prop>
+<D:prop xmlns:D="http://www.ietf.org/standards/dav/">
   <D:lockdiscovery>
     <D:activelock>
       <D:locktype>write</D:locktype>
diff --git a/result/dav12 b/result/dav12
index 9b6cbf1..d8d03fe 100644
--- a/result/dav12
+++ b/result/dav12
@@ -1,6 +1,2 @@
-
-
-------- test/dav12 -----------
 <?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:href>http://www.ics.uci.edu/~ejw/contact.html</D:href>
+<D:href xmlns:D="http://www.ietf.org/standards/dav/">http://www.ics.uci.edu/~ejw/contact.html</D:href>
diff --git a/result/dav13 b/result/dav13
index 9ce781c..425aa43 100644
--- a/result/dav13
+++ b/result/dav13
@@ -1,9 +1,5 @@
-
-
-------- test/dav13 -----------
 <?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:multistatus>
+<D:multistatus xmlns:D="http://www.ietf.org/standards/dav/">
   <D:response>
     <D:href>
                http://webdav.sb.aol.com/workspace/webdav/proposal.doc
diff --git a/result/dav14 b/result/dav14
deleted file mode 100644
index bf53797..0000000
--- a/result/dav14
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-------- test/dav14 -----------
-<?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/patch/" prefix="D"?>
-<D:resourceupdate>
-  <D:replace XML-SPACE="PRESERVE">
-    <D:octet-range>14</D:octet-range>
-003CTITLE003ENew
-   Title003C/TITLE003E  </D:replace>
-  <D:delete>
-    <D:octet-range>38-50</D:octet-range>
-  </D:delete>
-  <D:insert XML-SPACE="PRESERVE">
-    <D:octet-range>86</D:octet-range>
-003CP003ENew paragraph003C/P003E  </D:insert>
-</D:resourceupdate>
diff --git a/result/dav15 b/result/dav15
index 7703289..b80802e 100644
--- a/result/dav15
+++ b/result/dav15
@@ -1,10 +1,5 @@
-
-
-------- test/dav15 -----------
 <?xml version="1.0"?>
-<?xml:namespace ns="http://www.foocorp.com/Project/" prefix="F"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:prop>
+<D:prop xmlns:D="http://www.ietf.org/standards/dav/" xmlns:F="http://www.foocorp.com/Project/">
   <D:Source>
     <D:link>
       <F:projfiles>Source</F:projfiles>
diff --git a/result/dav16 b/result/dav16
index 3585ab1..9a7dc36 100644
--- a/result/dav16
+++ b/result/dav16
@@ -1,9 +1,5 @@
-
-
-------- test/dav16 -----------
 <?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:propfind>
+<D:propfind xmlns:D="http://www.ietf.org/standards/dav/">
   <D:prop>
     <lockdiscovery/>
   </D:prop>
diff --git a/result/dav17 b/result/dav17
index 30a10af..1137662 100644
--- a/result/dav17
+++ b/result/dav17
@@ -1,9 +1,5 @@
-
-
-------- test/dav17 -----------
 <?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:multistatus>
+<D:multistatus xmlns:D="http://www.ietf.org/standards/dav/">
   <D:response>
     <D:prop>
       <D:lockdiscovery>
diff --git a/result/dav18 b/result/dav18
index 245dbdb..3de1c19 100644
--- a/result/dav18
+++ b/result/dav18
@@ -1,9 +1,5 @@
-
-
-------- test/dav18 -----------
 <?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:propfind>
+<D:propfind xmlns:D="http://www.ietf.org/standards/dav/">
   <D:prop>
     <supportedlock/>
   </D:prop>
diff --git a/result/dav19 b/result/dav19
index b748232..9535ffc 100644
--- a/result/dav19
+++ b/result/dav19
@@ -1,9 +1,5 @@
-
-
-------- test/dav19 -----------
 <?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:multistatus>
+<D:multistatus xmlns:D="http://www.ietf.org/standards/dav/">
   <D:response>
     <D:prop>
       <D:supportedlock>
diff --git a/result/dav2 b/result/dav2
index f7efb03..f831b4b 100644
--- a/result/dav2
+++ b/result/dav2
@@ -1,10 +1,5 @@
-
-
-------- test/dav2 -----------
 <?xml version="1.0"?>
-<?xml:namespace ns="http://www.foo.bar/boxschema/" prefix="R"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="S"?>
-<S:multistatus>
+<S:multistatus xmlns:S="http://www.ietf.org/standards/dav/" xmlns:R="http://www.foo.bar/boxschema/">
   <S:response>
     <S:href>http://www.foo.bar/container/</S:href>
     <S:prop>
diff --git a/result/dav3 b/result/dav3
index c4c235a..986b3fe 100644
--- a/result/dav3
+++ b/result/dav3
@@ -1,10 +1,5 @@
-
-
-------- test/dav3 -----------
 <?xml version="1.0"?>
-<?xml:namespace ns="http://www.foo.bar/boxschema/" prefix="R"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:multistatus>
+<D:multistatus xmlns:D="http://www.ietf.org/standards/dav/" xmlns:R="http://www.foo.bar/boxschema/">
   <D:response>
     <D:href>http://www.foo.bar/container/</D:href>
     <D:prop>
diff --git a/result/dav4 b/result/dav4
index 3c38b64..9ab7ceb 100644
--- a/result/dav4
+++ b/result/dav4
@@ -1,10 +1,5 @@
-
-
-------- test/dav4 -----------
 <?xml version="1.0"?>
-<?xml:namespace ns="http://www.w3.com/standards/z39.50/" prefix="Z"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:propertyupdate>
+<D:propertyupdate xmlns:D="http://www.ietf.org/standards/dav/" xmlns:Z="http://www.w3.com/standards/z39.50/">
   <D:set>
     <D:prop>
       <Z:authors>
diff --git a/result/dav5 b/result/dav5
index cb8c1dd..4647496 100644
--- a/result/dav5
+++ b/result/dav5
@@ -1,10 +1,5 @@
-
-
-------- test/dav5 -----------
 <?xml version="1.0"?>
-<?xml:namespace ns="http://www.w3.com/standards/z39.50/" prefix="Z"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:multistatus>
+<D:multistatus xmlns:D="http://www.ietf.org/standards/dav/" xmlns:Z="http://www.w3.com/standards/z39.50/">
   <D:response>
     <D:prop>
       <Z:Authors/>
diff --git a/result/dav6 b/result/dav6
index 1fce59b..9dc1451 100644
--- a/result/dav6
+++ b/result/dav6
@@ -1,9 +1,5 @@
-
-
-------- test/dav6 -----------
 <?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:multistatus>
+<D:multistatus xmlns:D="http://www.ietf.org/standards/dav/">
   <D:response>
     <D:href>http://www.microsoft.com/user/yarong/dav_drafts/
           </D:href>
diff --git a/result/dav7 b/result/dav7
index 68f43ce..ec4a952 100644
--- a/result/dav7
+++ b/result/dav7
@@ -1,9 +1,5 @@
-
-
-------- test/dav7 -----------
 <?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="d"?>
-<d:multistatus>
+<d:multistatus xmlns:d="http://www.ietf.org/standards/dav/">
   <d:response>
     <d:href>http://www.foo.bar/container/resource1</d:href>
     <d:href>http://www.foo.bar/container/resource2</d:href>
diff --git a/result/dav8 b/result/dav8
index e285c19..7f99baf 100644
--- a/result/dav8
+++ b/result/dav8
@@ -1,9 +1,5 @@
-
-
-------- test/dav8 -----------
 <?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="d"?>
-<d:multistatus>
+<d:multistatus xmlns:d="http://www.ietf.org/standards/dav/">
   <d:response>
     <d:href>http://www.foo.bar/othercontainer/resource1</d:href>
     <d:href>http://www.foo.bar/othercontainer/resource2</d:href>
diff --git a/result/dav9 b/result/dav9
index 6c505b9..8ed63b8 100644
--- a/result/dav9
+++ b/result/dav9
@@ -1,9 +1,5 @@
-
-
-------- test/dav9 -----------
 <?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="d"?>
-<d:multistatus>
+<d:multistatus xmlns:d="http://www.ietf.org/standards/dav/">
   <d:response>
     <d:href>http://www.foo.bar/container/resource1</d:href>
     <d:href>http://www.foo.bar/container/resource2</d:href>
diff --git a/result/dtd1 b/result/dtd1
new file mode 100644
index 0000000..2cb4398
--- /dev/null
+++ b/result/dtd1
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<!DOCTYPE MEMO PUBLIC "-//SGMLSOURCE//DTD MEMO//EN" "http://www.sgmlsource.com/dtds/memo.dtd">
+<MEMO/>
diff --git a/result/ent1 b/result/ent1
new file mode 100644
index 0000000..14bf428
--- /dev/null
+++ b/result/ent1
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<!DOCTYPE EXAMPLE SYSTEM "example.dtd" [
+<!ENTITY xml "Extensible Markup Language">
+]>
+<EXAMPLE>
+    Extensible Markup Language
+</EXAMPLE>
diff --git a/result/ent2 b/result/ent2
new file mode 100644
index 0000000..754f257
--- /dev/null
+++ b/result/ent2
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<!DOCTYPE EXAMPLE SYSTEM "example.dtd" [
+<!ENTITY xml "Extensible Markup Language">
+<!ENTITY title PUBLIC "-//MY-TITLE//FR" "title.xml">
+<!ENTITY image SYSTEM "img.gif" NDATA GIF>
+]>
+<EXAMPLE>
+  
+  This text is about XML, the Extensible Markup Language and this is an embedded 
+</EXAMPLE>
diff --git a/result/ent3 b/result/ent3
new file mode 100644
index 0000000..b1c0b14
--- /dev/null
+++ b/result/ent3
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<!DOCTYPE EXAMPLE SYSTEM "example.dtd" [
+<!ENTITY xml "Extensible Markup Language">
+]>
+<EXAMPLE prop1="a&amp;b" prop2="Extensible Markup Language">
+  Test of entities in attributes.
+</EXAMPLE>
diff --git a/result/p3p b/result/p3p
index 41f5a35..75eec90 100644
--- a/result/p3p
+++ b/result/p3p
@@ -1,26 +1,22 @@
-
-
-------- test/p3p -----------
 <?xml version="1.0"?>
-<?xml:namespace ns="http://www.w3.org/TR/WD-rdf-syntax#" prefix="RDF"?>
-<RDF:RDF>
-  <PROP assurance="http://www.TrustUs.org" agreeID="94df1293a3e519bb" entity="CoolCatalog" realm="http://www.CoolCatalog.com/catalogue/">
+<RDF:RDF xmlns:p3p="http//www.w3.org/TR/1998/WD-P3P10-syntax#proposal.DTD" xmlns:RDF="http://www.w3.org/TR/WD-rdf-syntax#">
+  <PROP realm="http://www.CoolCatalog.com/catalogue/" entity="CoolCatalog" agreeID="94df1293a3e519bb" assurance="http://www.TrustUs.org">
     <USES>
-      <STATEMENT consq="a site with clothes you&apos;d appreciate." id="0" recpnt="0" purp="2,3">
+      <STATEMENT purp="2,3" recpnt="0" id="0" consq="a site with clothes you&apos;d appreciate.">
         <WITH>
           <PREFIX name="User.">
             <REF name="Name.First"/>
-            <REF optional="1" name="Bdate.Year"/>
+            <REF name="Bdate.Year" optional="1"/>
             <REF name="Gender"/>
           </PREFIX>
         </WITH>
       </STATEMENT>
     </USES>
     <USES>
-      <STATEMENT id="1" recpnt="0" purp="0" action="read&amp;write">
+      <STATEMENT action="read&amp;write" purp="0" recpnt="0" id="1">
         <REF name="User.Shipping."/>
       </STATEMENT>
     </USES>
-    <DISCLOSURE other="0,1" access="3" discURI="http://www.CoolCatalog.com/PrivacyPractice.html"/>
+    <DISCLOSURE discURI="http://www.CoolCatalog.com/PrivacyPractice.html" access="3" other="0,1"/>
   </PROP>
 </RDF:RDF>
diff --git a/result/rdf1 b/result/rdf1
new file mode 100644
index 0000000..d44c3c6
--- /dev/null
+++ b/result/rdf1
@@ -0,0 +1,81 @@
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RPM="http://www.rpm.org/" xmlns:RDF="http://www.w3.org/TR/WD-rdf-syntax#">
+  <RDF:Description HREF="ftp://rufus.w3.org/linux/redhat/redhat-5.1/i386/RedHat/RPMS/rpm-2.5-2.i386.rpm">
+    <RPM:Name>rpm</RPM:Name>
+    <RPM:Version>2.5</RPM:Version>
+    <RPM:Release>2</RPM:Release>
+    <RPM:Arch>i386</RPM:Arch>
+    <RPM:Os>Linux</RPM:Os>
+    <RPM:Distribution>Manhattan </RPM:Distribution>
+    <RPM:Vendor>Red Hat Software</RPM:Vendor>
+    <RPM:Packager>Red Hat Software &lt;bugs@redhat.com&gt;</RPM:Packager>
+    <RPM:Group>Utilities/System</RPM:Group>
+    <RPM:Summary>Red Hat Package Manager</RPM:Summary>
+    <RPM:Description>RPM is a powerful package manager, which can be used to build, install,
+query, verify, update, and uninstall individual software packages. A
+package consists of an archive of files, and package information, including
+name, version, and description.</RPM:Description>
+    <RPM:Copyright>GPL</RPM:Copyright>
+    <RPM:Changelog>* Sun May 10 1998 Prospector System &lt;bugs@redhat.com&gt;
+  - translations modified for de, fr, tr
+</RPM:Changelog>
+    <RPM:Sources>rpm-2.5-2.src.rpm</RPM:Sources>
+    <RPM:SourcesFtp>ftp://ftp.redhat.com/pub/redhat/redhat-5.1/SRPMS</RPM:SourcesFtp>
+    <RPM:BuildDate>Sun May 10 14:52:32 1998</RPM:BuildDate>
+    <RPM:Date>894826352</RPM:Date>
+    <RPM:Size>850599</RPM:Size>
+    <RPM:BuildHost>porky.redhat.com</RPM:BuildHost>
+    <RPM:Provides>
+      <RDF:Bag>
+        <RPM:Resource>rpm</RPM:Resource>
+      </RDF:Bag>
+    </RPM:Provides>
+    <RPM:Requires>
+      <RDF:Bag>
+        <RPM:Resource>/bin/sh</RPM:Resource>
+        <RPM:Resource>ld-linux.so.2</RPM:Resource>
+        <RPM:Resource>libc.so.6</RPM:Resource>
+        <RPM:Resource>libdb.so.2</RPM:Resource>
+        <RPM:Resource>libz.so.1</RPM:Resource>
+        <RPM:Resource>/bin/bash</RPM:Resource>
+        <RPM:Resource>/bin/sh</RPM:Resource>
+      </RDF:Bag>
+    </RPM:Requires>
+    <RPM:Files>/bin/rpm
+/usr/bin/find-provides
+/usr/bin/find-requires
+/usr/bin/gendiff
+/usr/bin/rpm2cpio
+/usr/doc/rpm-2.5
+/usr/doc/rpm-2.5/CHANGES
+/usr/doc/rpm-2.5/RPM-PGP-KEY
+/usr/doc/rpm-2.5/buildroot
+/usr/doc/rpm-2.5/dependencies
+/usr/doc/rpm-2.5/format
+/usr/doc/rpm-2.5/groups
+/usr/doc/rpm-2.5/macros
+/usr/doc/rpm-2.5/queryformat
+/usr/doc/rpm-2.5/relocatable
+/usr/doc/rpm-2.5/signatures
+/usr/doc/rpm-2.5/spec
+/usr/doc/rpm-2.5/triggers
+/usr/lib/rpmpopt
+/usr/lib/rpmrc
+/usr/man/man8/rpm.8
+/usr/man/man8/rpm2cpio.8
+/usr/share/locale/de/LC_MESSAGES/rpm.mo
+/usr/share/locale/fr/LC_MESSAGES/rpm.mo
+/usr/share/locale/pt-br/LC_MESSAGES/rpm.mo
+/usr/share/locale/sv/LC_MESSAGES/rpm.mo
+/usr/share/locale/tr/LC_MESSAGES/rpm.mo
+/usr/src/redhat
+/usr/src/redhat/BUILD
+/usr/src/redhat/RPMS
+/usr/src/redhat/RPMS/i386
+/usr/src/redhat/RPMS/noarch
+/usr/src/redhat/SOURCES
+/usr/src/redhat/SPECS
+/usr/src/redhat/SRPMS
+</RPM:Files>
+  </RDF:Description>
+</RDF:RDF>
diff --git a/test/dav1 b/test/dav1
index e7ad9e6..47b66bf 100644
--- a/test/dav1
+++ b/test/dav1
@@ -1,4 +1,4 @@
-   <?XML version="1.0">
+   <?XML version="1.0"?>
    <?namespace href ="http://www.ietf.org/standards/dav/" AS = "D"?>
    <?namespace href = "http://www.foo.bar/boxschema" AS = "R"?>
    <D:multistatus>
diff --git a/test/dav10 b/test/dav10
index 4a444b9..aa7f94f 100644
--- a/test/dav10
+++ b/test/dav10
@@ -1,4 +1,4 @@
-   <?XML version="1.0">
+   <?XML version="1.0"?>
    <?namespace href="http://www.ietf.org/standards/dav/" AS = "D"?>
    <D:owner>
       <D:href>http://www.ics.uci.edu/~ejw/contact.html</D:href>
diff --git a/test/dav11 b/test/dav11
index ece73dc..99e777b 100644
--- a/test/dav11
+++ b/test/dav11
@@ -1,4 +1,4 @@
-   <?XML version="1.0">
+   <?XML version="1.0"?>
    <?namespace href ="http://www.ietf.org/standards/dav/" AS = "D"?>
    <D:prop>
      <D:lockdiscovery>
diff --git a/test/dav12 b/test/dav12
index 47a1a9d..eff2139 100644
--- a/test/dav12
+++ b/test/dav12
@@ -1,3 +1,3 @@
-   <?XML version="1.0">
+   <?XML version="1.0"?>
    <?namespace href="http://www.ietf.org/standards/dav/" AS = "D"?>
    <D:href>http://www.ics.uci.edu/~ejw/contact.html</D:href>
diff --git a/test/dav13 b/test/dav13
index df92ae5..bb83088 100644
--- a/test/dav13
+++ b/test/dav13
@@ -1,4 +1,4 @@
-   <?XML version="1.0">
+   <?XML version="1.0"?>
    <?namespace href = "http://www.ietf.org/standards/dav/" AS = "D"?>
    <D:multistatus>
      <D:response>
diff --git a/test/dav14 b/test/dav14
deleted file mode 100644
index 7fe8bf4..0000000
--- a/test/dav14
+++ /dev/null
@@ -1,10 +0,0 @@
-   <?XML version="1.0">
-   <?namespace href = "http://www.ietf.org/standards/dav/patch/" AS =
-   "D"?>
-   <D:resourceupdate>
-     <D:replace XML-SPACE = "PRESERVE">
-          <D:octet-range>14</D:octet-range>&003CTITLE&003ENew
-   Title&003C/TITLE&003E</D:replace>
-     <D:delete><D:octet-range>38-50</D:octet-range></D:delete>
-     <D:insert XML-SPACE = "PRESERVE"><D:octet-range>86</D:octet-range>&003CP&003ENew paragraph&003C/P&003E</D:insert>
-   </D:resourceupdate>
diff --git a/test/dav15 b/test/dav15
index 1d35430..201e90a 100644
--- a/test/dav15
+++ b/test/dav15
@@ -1,4 +1,4 @@
-   <?XML version="1.0">
+   <?XML version="1.0"?>
    <?namespace href = "http://www.ietf.org/standards/dav/" AS = "D"?>
    <?namespace href = "http://www.foocorp.com/Project/" AS = "F"?>
    <D:prop>
diff --git a/test/dav16 b/test/dav16
index 29fe256..ea4d7b8 100644
--- a/test/dav16
+++ b/test/dav16
@@ -1,4 +1,4 @@
-   <?XML version="1.0">
+   <?XML version="1.0"?>
    <?namespace href = "http://www.ietf.org/standards/dav/" AS = "D"?>
    <D:propfind>
      <D:prop><lockdiscovery/></D:prop>
diff --git a/test/dav17 b/test/dav17
index f1dabda..4aa20c8 100644
--- a/test/dav17
+++ b/test/dav17
@@ -1,4 +1,4 @@
-   <?XML version="1.0">
+   <?XML version="1.0"?>
    <?namespace href ="http://www.ietf.org/standards/dav/" AS = "D"?>
    <D:multistatus>
      <D:response>
diff --git a/test/dav18 b/test/dav18
index 545c7e5..cdf5daa 100644
--- a/test/dav18
+++ b/test/dav18
@@ -1,4 +1,4 @@
-   <?XML version="1.0">
+   <?XML version="1.0"?>
    <?namespace href = "http://www.ietf.org/standards/dav/" AS = "D"?>
    <D:propfind>
      <D:prop><supportedlock/></D:prop>
diff --git a/test/dav19 b/test/dav19
index e75fedb..d6d2e96 100644
--- a/test/dav19
+++ b/test/dav19
@@ -1,4 +1,4 @@
-   <?XML version="1.0">
+   <?XML version="1.0"?>
    <?namespace href ="http://www.ietf.org/standards/dav/" AS = "D"?>
    <D:multistatus>
      <D:response>
diff --git a/test/dav2 b/test/dav2
index 2b73d5f..af100a8 100644
--- a/test/dav2
+++ b/test/dav2
@@ -1,4 +1,4 @@
-   <?XML version="1.0">
+   <?XML version="1.0"?>
    <?namespace href = "http://www.ietf.org/standards/dav/" AS = "S"?>
    <?namespace href = "http://www.foo.bar/boxschema/" AS = "R"?>
    <S:multistatus>
diff --git a/test/dav3 b/test/dav3
index 964f344..7618a41 100644
--- a/test/dav3
+++ b/test/dav3
@@ -1,4 +1,4 @@
-   <?XML version="1.0">
+   <?XML version="1.0"?>
    <?namespace href = "http://www.ietf.org/standards/dav/" AS = "D"?>
    <?namespace href = "http://www.foo.bar/boxschema/" AS = "R"?>
    <D:multistatus>
diff --git a/test/dav4 b/test/dav4
index 26f6153..4ba4ad9 100644
--- a/test/dav4
+++ b/test/dav4
@@ -1,4 +1,4 @@
-   <?XML version="1.0">
+   <?XML version="1.0"?>
    <?namespace href = "http://www.ietf.org/standards/dav/" AS = "D"?>
    <?namespace href = "http://www.w3.com/standards/z39.50/" AS = "Z"?>
    <D:propertyupdate>
diff --git a/test/dav5 b/test/dav5
index b51b0f8..ee9fa37 100644
--- a/test/dav5
+++ b/test/dav5
@@ -1,4 +1,4 @@
-   <?XML version="1.0">
+   <?XML version="1.0"?>
    <?namespace href="http://www.ietf.org/standards/dav/" AS = "D"?>
    <?namespace href="http://www.w3.com/standards/z39.50/" AS = "Z"?>
    <D:multistatus>
diff --git a/test/dav6 b/test/dav6
index b970c8a..929848a 100644
--- a/test/dav6
+++ b/test/dav6
@@ -1,4 +1,4 @@
-   <?XML version="1.0">
+   <?XML version="1.0"?>
    <?namespace href = "http://www.ietf.org/standards/dav/" AS = "D"?>
    <D:multistatus>
      <D:response>
diff --git a/test/dav7 b/test/dav7
index 7ed12fa..feafe39 100644
--- a/test/dav7
+++ b/test/dav7
@@ -1,4 +1,4 @@
-   <?XML version="1.0">
+   <?XML version="1.0"?>
    <?namespace href = "http://www.ietf.org/standards/dav/" AS = "d"?>
    <d:multistatus>
      <d:response>
diff --git a/test/dav8 b/test/dav8
index b5c0c6b..220ebe3 100644
--- a/test/dav8
+++ b/test/dav8
@@ -1,4 +1,4 @@
-   <?XML version="1.0">
+   <?XML version="1.0"?>
    <?namespace href = "http://www.ietf.org/standards/dav/" AS = "d"?>
    <d:multistatus>
      <d:response>
diff --git a/test/dav9 b/test/dav9
index a1dfa43..4201300 100644
--- a/test/dav9
+++ b/test/dav9
@@ -1,4 +1,4 @@
-   <?XML version="1.0">
+   <?XML version="1.0"?>
    <?namespace href = "http://www.ietf.org/standards/dav/" AS = "d"?>
    <d:multistatus>
      <d:response>
diff --git a/test/dtd1 b/test/dtd1
new file mode 100644
index 0000000..35c9dc7
--- /dev/null
+++ b/test/dtd1
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<!DOCTYPE MEMO PUBLIC "-//SGMLSOURCE//DTD MEMO//EN" 
+                      "http://www.sgmlsource.com/dtds/memo.dtd">
+<MEMO>
+</MEMO>
diff --git a/test/ent1 b/test/ent1
new file mode 100644
index 0000000..3e24756
--- /dev/null
+++ b/test/ent1
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<!DOCTYPE EXAMPLE SYSTEM "example.dtd" [
+<!ENTITY xml "Extensible Markup Language">
+]>
+<EXAMPLE>
+    &xml;
+</EXAMPLE>
diff --git a/test/ent2 b/test/ent2
new file mode 100644
index 0000000..533f5a3
--- /dev/null
+++ b/test/ent2
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<!DOCTYPE EXAMPLE SYSTEM "example.dtd" [
+<!ENTITY xml "Extensible Markup Language">
+<!ENTITY title PUBLIC "-//MY-TITLE//FR" "title.xml">
+<!ENTITY image SYSTEM "img.gif" NDATA GIF>
+]>
+<EXAMPLE>
+  &title;
+  This text is about XML, the &xml; and this is an embedded &image;
+</EXAMPLE>
+
diff --git a/test/ent3 b/test/ent3
new file mode 100644
index 0000000..f9803b8
--- /dev/null
+++ b/test/ent3
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<!DOCTYPE EXAMPLE SYSTEM "example.dtd" [
+<!ENTITY xml "Extensible Markup Language">
+]>
+<EXAMPLE prop1="a&amp;b" prop2="&xml;">
+  Test of entities in attributes.
+</EXAMPLE>
+
diff --git a/test/p3p b/test/p3p
index 1a83af2..d21325e 100644
--- a/test/p3p
+++ b/test/p3p
@@ -1,3 +1,4 @@
+<?xml version="1.0"?>
 <?xml:namespace ns="http//www.w3.org/TR/1998/WD-P3P10-syntax#proposal.DTD" prefix="p3p"?>
 <?xml:namespace ns="http://www.w3.org/TR/WD-rdf-syntax#" prefix="RDF"?>
 <RDF:RDF><PROP realm="http://www.CoolCatalog.com/catalogue/" 
diff --git a/test/rdf1 b/test/rdf1
new file mode 100644
index 0000000..ea6763e
--- /dev/null
+++ b/test/rdf1
@@ -0,0 +1,83 @@
+<?XML version="1.0"?>
+<?namespace href="http://www.rpm.org/" AS="RPM"?>
+<?namespace href="http://www.w3.org/TR/WD-rdf-syntax#" AS="RDF"?>
+<RDF:RDF>
+  <RDF:Description RDF:HREF="ftp://rufus.w3.org/linux/redhat/redhat-5.1/i386/RedHat/RPMS/rpm-2.5-2.i386.rpm">
+    <RPM:Name>rpm</RPM:Name>
+    <RPM:Version>2.5</RPM:Version>
+    <RPM:Release>2</RPM:Release>
+    <RPM:Arch>i386</RPM:Arch>
+    <RPM:Os>Linux</RPM:Os>
+    <RPM:Distribution>Manhattan </RPM:Distribution>
+    <RPM:Vendor>Red Hat Software</RPM:Vendor>
+    <RPM:Packager>Red Hat Software &lt;bugs@redhat.com&gt;</RPM:Packager>
+    <RPM:Group>Utilities/System</RPM:Group>
+    <RPM:Summary>Red Hat Package Manager</RPM:Summary>
+    <RPM:Description>RPM is a powerful package manager, which can be used to build, install,
+query, verify, update, and uninstall individual software packages. A
+package consists of an archive of files, and package information, including
+name, version, and description.</RPM:Description>
+    <RPM:Copyright>GPL</RPM:Copyright>
+    <RPM:Changelog>* Sun May 10 1998 Prospector System &lt;bugs@redhat.com&gt;
+  - translations modified for de, fr, tr
+</RPM:Changelog>
+    <RPM:Sources>rpm-2.5-2.src.rpm</RPM:Sources>
+    <RPM:SourcesFtp>ftp://ftp.redhat.com/pub/redhat/redhat-5.1/SRPMS</RPM:SourcesFtp>
+    <RPM:BuildDate>Sun May 10 14:52:32 1998</RPM:BuildDate>
+    <RPM:Date>894826352</RPM:Date>
+    <RPM:Size>850599</RPM:Size>
+    <RPM:BuildHost>porky.redhat.com</RPM:BuildHost>
+    <RPM:Provides>
+      <RDF:Bag>
+        <RPM:Resource>rpm</RPM:Resource>
+      </RDF:Bag>
+    </RPM:Provides>
+    <RPM:Requires>
+      <RDF:Bag>
+        <RPM:Resource>/bin/sh</RPM:Resource>
+        <RPM:Resource>ld-linux.so.2</RPM:Resource>
+        <RPM:Resource>libc.so.6</RPM:Resource>
+        <RPM:Resource>libdb.so.2</RPM:Resource>
+        <RPM:Resource>libz.so.1</RPM:Resource>
+        <RPM:Resource>/bin/bash</RPM:Resource>
+        <RPM:Resource>/bin/sh</RPM:Resource>
+      </RDF:Bag>
+    </RPM:Requires>
+    <RPM:Files>/bin/rpm
+/usr/bin/find-provides
+/usr/bin/find-requires
+/usr/bin/gendiff
+/usr/bin/rpm2cpio
+/usr/doc/rpm-2.5
+/usr/doc/rpm-2.5/CHANGES
+/usr/doc/rpm-2.5/RPM-PGP-KEY
+/usr/doc/rpm-2.5/buildroot
+/usr/doc/rpm-2.5/dependencies
+/usr/doc/rpm-2.5/format
+/usr/doc/rpm-2.5/groups
+/usr/doc/rpm-2.5/macros
+/usr/doc/rpm-2.5/queryformat
+/usr/doc/rpm-2.5/relocatable
+/usr/doc/rpm-2.5/signatures
+/usr/doc/rpm-2.5/spec
+/usr/doc/rpm-2.5/triggers
+/usr/lib/rpmpopt
+/usr/lib/rpmrc
+/usr/man/man8/rpm.8
+/usr/man/man8/rpm2cpio.8
+/usr/share/locale/de/LC_MESSAGES/rpm.mo
+/usr/share/locale/fr/LC_MESSAGES/rpm.mo
+/usr/share/locale/pt-br/LC_MESSAGES/rpm.mo
+/usr/share/locale/sv/LC_MESSAGES/rpm.mo
+/usr/share/locale/tr/LC_MESSAGES/rpm.mo
+/usr/src/redhat
+/usr/src/redhat/BUILD
+/usr/src/redhat/RPMS
+/usr/src/redhat/RPMS/i386
+/usr/src/redhat/RPMS/noarch
+/usr/src/redhat/SOURCES
+/usr/src/redhat/SPECS
+/usr/src/redhat/SRPMS
+</RPM:Files>
+  </RDF:Description>
+</RDF:RDF>
diff --git a/tester.c b/tester.c
index 030ee1c..0075ad7 100644
--- a/tester.c
+++ b/tester.c
@@ -6,20 +6,33 @@
  * $Id$
  */
 
+#ifdef WIN32
+#define HAVE_FCNTL_H
+#include <io.h>
+#else
+#include <config.h>
+#endif
 #include <sys/types.h>
+#ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
 #include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
+#endif
 #include <stdio.h>
 #include <string.h>
 #include <malloc.h>
 
-#include "xml_parser.h"
-#include "xml_tree.h"
+#include "parser.h"
+#include "tree.h"
 
-#define MAX_BUF	500000
-
-static CHAR buffer[MAX_BUF] = 
+/*
+ * Note: there is a couple of errors introduced on purpose.
+ */
+static CHAR buffer[] = 
 "\n\
 <?xml version=\"1.0\">\n\
 <?xml:namespace ns = \"http://www.ietf.org/standards/dav/\" prefix = \"D\"?>\n\
@@ -40,37 +53,31 @@
 \n\
 ";
 
-int readFile(char *filename) {
-    int input;
-    int res;
 
-    memset(buffer, 0, sizeof(buffer));
-    input = open (filename, O_RDONLY);
-    if (input < 0) {
-        fprintf (stderr, "Cannot read file %s :\n", filename);
-	perror ("open failed");
-	return(-1);
-    }
-    res = read(input, buffer, sizeof(buffer));
-    if (res < 0) {
-        fprintf (stderr, "Cannot read file %s :\n", filename);
-	perror ("read failed");
-	return(-1);
-    }
-    if (res >= MAX_BUF) {
-        fprintf (stderr, "Read only %d byte of %s, increase MAX_BUF\n",
-	         res, filename);
-        return(-1);
-    }
-    close(input);
-    return(res);
-}
-
-void parseAndPrint(CHAR *buf) {
+void parseAndPrintFile(char *filename) {
     xmlDocPtr doc;
 
     /*
-     * build a fake XML document from a string;
+     * build an XML tree from a string;
+     */
+    doc = xmlParseFile(filename);
+
+    /*
+     * print it.
+     */
+    xmlDocDump(stdout, doc);
+
+    /*
+     * free it.
+     */
+    xmlFreeDoc(doc);
+}
+
+void parseAndPrintBuffer(CHAR *buf) {
+    xmlDocPtr doc;
+
+    /*
+     * build an XML tree from a string;
      */
     doc = xmlParseDoc(buf);
 
@@ -90,13 +97,10 @@
 
     if (argc > 1) {
         for (i = 1; i < argc ; i++) {
-	    if (readFile(argv[i]) >= 0) {
-	        printf("\n\n------- %s -----------\n", argv[i]);
-	        parseAndPrint(buffer);
-	    }
+	    parseAndPrintFile(argv[i]);
 	}
     } else
-        parseAndPrint(buffer);
+        parseAndPrintBuffer(buffer);
 
     return(0);
 }
diff --git a/tree.c b/tree.c
new file mode 100644
index 0000000..59d8454
--- /dev/null
+++ b/tree.c
@@ -0,0 +1,1209 @@
+/*
+ * tree.c : implemetation of access function for an XML tree.
+ *
+ * See Copyright for the status of this software.
+ *
+ * $Id$
+ *
+ * TODO Cleanup the Dump mechanism.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <malloc.h>
+#include <string.h> /* for memset() only ! */
+
+#include "tree.h"
+#include "entities.h"
+
+static CHAR xmlStringText[] = { 't', 'e', 'x', 't', 0 };
+int oldXMLWDcompatibility = 0;
+int xmlIndentTreeOutput = 1;
+
+/************************************************************************
+ *									*
+ *		Allocation and deallocation of basic structures		*
+ *									*
+ ************************************************************************/
+ 
+/*
+ * Upgrade old Namespace and move them to the root of the document.
+ */
+
+void xmlUpgradeOldNs(xmlDocPtr doc) {
+    xmlNsPtr cur;
+
+    if ((doc == NULL) || (doc->oldNs == NULL)) return;
+    if (doc->root == NULL) {
+        fprintf(stderr, "xmlUpgradeOldNs: failed no root !\n");
+	return;
+    }
+
+    cur = doc->oldNs;
+    while (cur->next != NULL) {
+	cur->type = XML_LOCAL_NAMESPACE;
+        cur = cur->next;
+    }
+    cur->type = XML_LOCAL_NAMESPACE;
+    cur->next = doc->root->nsDef;
+    doc->root->nsDef = doc->oldNs;
+    doc->oldNs = NULL;
+}
+
+/*
+ * Creation of a new Namespace.
+ */
+xmlNsPtr xmlNewNs(xmlNodePtr node, const CHAR *href, const CHAR *prefix) {
+    xmlNsPtr cur;
+
+    if (href == NULL) {
+        fprintf(stderr, "xmlNewNs: href == NULL !\n");
+	return(NULL);
+    }
+
+    /*
+     * Allocate a new DTD and fill the fields.
+     */
+    cur = (xmlNsPtr) malloc(sizeof(xmlNs));
+    if (cur == NULL) {
+        fprintf(stderr, "xmlNewNs : malloc failed\n");
+	return(NULL);
+    }
+
+    cur->type = XML_LOCAL_NAMESPACE;
+    if (href != NULL)
+	cur->href = xmlStrdup(href); 
+    else
+        cur->href = NULL;
+    if (prefix != NULL)
+	cur->prefix = xmlStrdup(prefix); 
+    else
+        cur->prefix = NULL;
+
+    /*
+     * Add it at the end to preserve parsing order ...
+     */
+    cur->next = NULL;
+    if (node != NULL) {
+	if (node->nsDef == NULL) {
+	    node->nsDef = cur;
+	} else {
+	    xmlNsPtr prev = node->nsDef;
+
+	    while (prev->next != NULL) prev = prev->next;
+	    prev->next = cur;
+	}
+    }
+
+    return(cur);
+}
+
+/*
+ * Creation of a new global namespace (the old way ...).
+ */
+xmlNsPtr xmlNewGlobalNs(xmlDocPtr doc, const CHAR *href, const CHAR *prefix) {
+    xmlNsPtr cur;
+
+    /*
+     * Allocate a new DTD and fill the fields.
+     */
+    cur = (xmlNsPtr) malloc(sizeof(xmlNs));
+    if (cur == NULL) {
+        fprintf(stderr, "xmlNewNs : malloc failed\n");
+	return(NULL);
+    }
+
+    cur->type = XML_GLOBAL_NAMESPACE;
+    if (href != NULL)
+	cur->href = xmlStrdup(href); 
+    else
+        cur->href = NULL;
+    if (prefix != NULL)
+	cur->prefix = xmlStrdup(prefix); 
+    else
+        cur->prefix = NULL;
+
+    /*
+     * Add it at the end to preserve parsing order ...
+     */
+    cur->next = NULL;
+    if (doc != NULL) {
+	if (doc->oldNs == NULL) {
+	    doc->oldNs = cur;
+	} else {
+	    xmlNsPtr prev = doc->oldNs;
+
+	    while (prev->next != NULL) prev = prev->next;
+	    prev->next = cur;
+	}
+    }
+
+    return(cur);
+}
+
+/*
+ * Set the node namespace a posteriori
+ */
+void xmlSetNs(xmlNodePtr node, xmlNsPtr ns) {
+    if (node == NULL) {
+        fprintf(stderr, "xmlSetNs: node == NULL\n");
+	return;
+    }
+    node->ns = ns;
+}
+
+/*
+ * Freeing a Namespace
+ */
+void xmlFreeNs(xmlNsPtr cur) {
+    if (cur == NULL) {
+        fprintf(stderr, "xmlFreeNs : ns == NULL\n");
+	return;
+    }
+    if (cur->href != NULL) free((char *) cur->href);
+    if (cur->prefix != NULL) free((char *) cur->prefix);
+    memset(cur, -1, sizeof(xmlNs));
+    free(cur);
+}
+
+/*
+ * Freeing a Namespace list
+ */
+void xmlFreeNsList(xmlNsPtr cur) {
+    xmlNsPtr next;
+    if (cur == NULL) {
+        fprintf(stderr, "xmlFreeNsList : ns == NULL\n");
+	return;
+    }
+    while (cur != NULL) {
+        next = cur->next;
+        xmlFreeNs(cur);
+	cur = next;
+    }
+}
+
+/*
+ * Creation of a new DTD.
+ */
+xmlDtdPtr xmlNewDtd(xmlDocPtr doc, const CHAR *name,
+                    const CHAR *ExternalID, const CHAR *SystemID) {
+    xmlDtdPtr cur;
+
+    if (doc->dtd != NULL) {
+        fprintf(stderr, "xmlNewDtd(%s): document %s already have a DTD %s\n",
+	/* !!! */ (char *) name, doc->name, /* !!! */ (char *)doc->dtd->name);
+    }
+
+    /*
+     * Allocate a new DTD and fill the fields.
+     */
+    cur = (xmlDtdPtr) malloc(sizeof(xmlDtd));
+    if (cur == NULL) {
+        fprintf(stderr, "xmlNewNs : malloc failed\n");
+	return(NULL);
+    }
+
+    if (name != NULL)
+	cur->name = xmlStrdup(name); 
+    else
+        cur->name = NULL;
+    if (ExternalID != NULL)
+	cur->ExternalID = xmlStrdup(ExternalID); 
+    else
+        cur->ExternalID = NULL;
+    if (SystemID != NULL)
+	cur->SystemID = xmlStrdup(SystemID); 
+    else
+        cur->SystemID = NULL;
+    cur->elements = NULL;
+    cur->entities = NULL;
+    doc->dtd = cur;
+
+    return(cur);
+}
+
+/*
+ * Freeing a DTD
+ */
+void xmlFreeDtd(xmlDtdPtr cur) {
+    if (cur == NULL) {
+        fprintf(stderr, "xmlFreeDtd : DTD == NULL\n");
+	return;
+    }
+    if (cur->name != NULL) free((char *) cur->name);
+    if (cur->SystemID != NULL) free((char *) cur->SystemID);
+    if (cur->ExternalID != NULL) free((char *) cur->ExternalID);
+    if (cur->elements != NULL)
+        fprintf(stderr, "xmlFreeDtd: cur->elements != NULL !!! \n");
+    if (cur->entities != NULL)
+        xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->entities);
+    memset(cur, -1, sizeof(xmlDtd));
+    free(cur);
+}
+
+/*
+ * Creation of a new document
+ */
+xmlDocPtr xmlNewDoc(const CHAR *version) {
+    xmlDocPtr cur;
+
+    if (version == NULL) {
+        fprintf(stderr, "xmlNewDoc : version == NULL\n");
+	return(NULL);
+    }
+
+    /*
+     * Allocate a new document and fill the fields.
+     */
+    cur = (xmlDocPtr) malloc(sizeof(xmlDoc));
+    if (cur == NULL) {
+        fprintf(stderr, "xmlNewDoc : malloc failed\n");
+	return(NULL);
+    }
+
+    cur->version = xmlStrdup(version); 
+    cur->name = NULL;
+    cur->root = NULL; 
+    cur->dtd = NULL;
+    cur->oldNs = NULL;
+    cur->encoding = NULL;
+    cur->entities = NULL;
+    cur->standalone = -1;
+    return(cur);
+}
+
+/*
+ * Freeing a document : all the tree is freed too.
+ */
+void xmlFreeDoc(xmlDocPtr cur) {
+    if (cur == NULL) {
+        fprintf(stderr, "xmlFreeDoc : document == NULL\n");
+	return;
+    }
+    free((char *) cur->version);
+    if (cur->name != NULL) free((char *) cur->name);
+    if (cur->encoding != NULL) free((char *) cur->encoding);
+    if (cur->root != NULL) xmlFreeNode(cur->root);
+    if (cur->dtd != NULL) xmlFreeDtd(cur->dtd);
+    if (cur->entities != NULL)
+        xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->entities);
+    memset(cur, -1, sizeof(xmlDoc));
+    free(cur);
+}
+
+/*
+ * Creation of a new property of a node.
+ */
+xmlAttrPtr xmlNewProp(xmlNodePtr node, const CHAR *name, const CHAR *value) {
+    xmlAttrPtr cur;
+
+    if (name == NULL) {
+        fprintf(stderr, "xmlNewProp : name == NULL\n");
+	return(NULL);
+    }
+
+    /*
+     * Allocate a new property and fill the fields.
+     */
+    cur = (xmlAttrPtr) malloc(sizeof(xmlAttr));
+    if (cur == NULL) {
+        fprintf(stderr, "xmlNewProp : malloc failed\n");
+	return(NULL);
+    }
+
+    cur->node = node; 
+    cur->name = xmlStrdup(name);
+    if (value != NULL)
+	cur->value = xmlStrdup(value);
+    else 
+	cur->value = NULL;
+
+    /*
+     * Add it at the end to preserve parsing order ...
+     */
+    cur->next = NULL;
+    if (node != NULL) {
+	if (node->properties == NULL) {
+	    node->properties = cur;
+	} else {
+	    xmlAttrPtr prev = node->properties;
+
+	    while (prev->next != NULL) prev = prev->next;
+	    prev->next = cur;
+	}
+    }
+    return(cur);
+}
+
+/*
+ * Freeing a property list : Free a property and all its siblings,
+ *                       this is a recursive behaviour, all the childs
+ *                       are freed too.
+ */
+void xmlFreePropList(xmlAttrPtr cur) {
+    xmlAttrPtr next;
+    if (cur == NULL) {
+        fprintf(stderr, "xmlFreePropList : property == NULL\n");
+	return;
+    }
+    while (cur != NULL) {
+        next = cur->next;
+        xmlFreeProp(cur);
+	cur = next;
+    }
+}
+
+/*
+ * Freeing a property.
+ */
+void xmlFreeProp(xmlAttrPtr cur) {
+    if (cur == NULL) {
+        fprintf(stderr, "xmlFreeProp : property == NULL\n");
+	return;
+    }
+    if (cur->name != NULL) free((char *) cur->name);
+    if (cur->value != NULL) free((char *) cur->value);
+    memset(cur, -1, sizeof(xmlAttr));
+    free(cur);
+}
+
+/*
+ * Creation of a new node element in a given DTD.
+ * We assume that the "name" has already being strdup'd !
+ */
+xmlNodePtr xmlNewNode(xmlNsPtr ns, const CHAR *name, CHAR *content) {
+    xmlNodePtr cur;
+
+    if (name == NULL) {
+        fprintf(stderr, "xmlNewNode : name == NULL\n");
+	return(NULL);
+    }
+
+    /*
+     * Allocate a new node and fill the fields.
+     */
+    cur = (xmlNodePtr) malloc(sizeof(xmlNode));
+    if (cur == NULL) {
+        fprintf(stderr, "xmlNewNode : malloc failed\n");
+	return(NULL);
+    }
+
+    cur->parent = NULL; 
+    cur->next = NULL; 
+    cur->childs = NULL; 
+    cur->properties = NULL; 
+    cur->type = 0;
+    cur->name = xmlStrdup(name);
+    cur->ns = ns;
+    cur->nsDef = NULL;
+    if (content != NULL)
+	cur->content = xmlStrdup(content);
+    else 
+	cur->content = NULL;
+    return(cur);
+}
+
+/*
+ * Creation of a new node contening text.
+ */
+xmlNodePtr xmlNewText(const CHAR *content) {
+    xmlNodePtr cur;
+
+    /*
+     * Allocate a new node and fill the fields.
+     */
+    cur = (xmlNodePtr) malloc(sizeof(xmlNode));
+    if (cur == NULL) {
+        fprintf(stderr, "xmlNewText : malloc failed\n");
+	return(NULL);
+    }
+
+    cur->parent = NULL; 
+    cur->next = NULL; 
+    cur->childs = NULL; 
+    cur->properties = NULL; 
+    cur->type = XML_TYPE_TEXT;
+    cur->name = xmlStrdup(xmlStringText);
+    cur->ns = NULL;
+    cur->nsDef = NULL;
+    if (content != NULL)
+	cur->content = xmlStrdup(content);
+    else 
+	cur->content = NULL;
+    return(cur);
+}
+
+/*
+ * Creation of a new node contening text.
+ */
+xmlNodePtr xmlNewTextLen(const CHAR *content, int len) {
+    xmlNodePtr cur;
+
+    /*
+     * Allocate a new node and fill the fields.
+     */
+    cur = (xmlNodePtr) malloc(sizeof(xmlNode));
+    if (cur == NULL) {
+        fprintf(stderr, "xmlNewText : malloc failed\n");
+	return(NULL);
+    }
+
+    cur->parent = NULL; 
+    cur->next = NULL; 
+    cur->childs = NULL; 
+    cur->properties = NULL; 
+    cur->type = XML_TYPE_TEXT;
+    cur->name = xmlStrdup(xmlStringText);
+    cur->ns = NULL;
+    cur->nsDef = NULL;
+    if (content != NULL)
+	cur->content = xmlStrndup(content, len);
+    else 
+	cur->content = NULL;
+    return(cur);
+}
+
+/*
+ * Creation of a new node contening a comment.
+ */
+xmlNodePtr xmlNewComment(CHAR *content) {
+    xmlNodePtr cur;
+
+    /*
+     * Allocate a new node and fill the fields.
+     */
+    cur = (xmlNodePtr) malloc(sizeof(xmlNode));
+    if (cur == NULL) {
+        fprintf(stderr, "xmlNewComment : malloc failed\n");
+	return(NULL);
+    }
+
+    cur->parent = NULL; 
+    cur->next = NULL; 
+    cur->childs = NULL; 
+    cur->properties = NULL; 
+    cur->type = XML_TYPE_COMMENT;
+    cur->name = xmlStrdup(xmlStringText);
+    cur->ns = NULL;
+    cur->nsDef = NULL;
+    if (content != NULL)
+	cur->content = xmlStrdup(content);
+    else 
+	cur->content = NULL;
+    return(cur);
+}
+
+/*
+ * Creation of a new child element, added at the end.
+ */
+xmlNodePtr xmlNewChild(xmlNodePtr parent, xmlNsPtr ns,
+                       const CHAR *name, CHAR *content) {
+    xmlNodePtr cur, prev;
+
+    if (parent == NULL) {
+        fprintf(stderr, "xmlNewChild : parent == NULL\n");
+	return(NULL);
+    }
+
+    if (name == NULL) {
+        fprintf(stderr, "xmlNewChild : name == NULL\n");
+	return(NULL);
+    }
+
+    /*
+     * Allocate a new node
+     */
+    if (ns == NULL)
+	cur = xmlNewNode(parent->ns, name, content);
+    else
+	cur = xmlNewNode(ns, name, content);
+    if (cur == NULL) return(NULL);
+
+    /*
+     * add the new element at the end of the childs list.
+     */
+    cur->parent = parent;
+    if (parent->childs == NULL) {
+        parent->childs = cur;
+    } else {
+        prev = parent->childs;
+	while (prev->next != NULL) prev = prev->next;
+	prev->next = cur;
+    }
+
+    return(cur);
+}
+
+/*
+ * Add a new child element, added at the end.
+ */
+xmlNodePtr xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
+    xmlNodePtr prev;
+
+    if (parent == NULL) {
+        fprintf(stderr, "xmladdChild : parent == NULL\n");
+	return(NULL);
+    }
+
+    if (cur == NULL) {
+        fprintf(stderr, "xmladdChild : child == NULL\n");
+	return(NULL);
+    }
+
+    /*
+     * add the new element at the end of the childs list.
+     */
+    cur->parent = parent;
+    if (parent->childs == NULL) {
+        parent->childs = cur;
+    } else {
+        prev = parent->childs;
+	while (prev->next != NULL) prev = prev->next;
+	prev->next = cur;
+    }
+
+    return(cur);
+}
+
+/*
+ * Search the last child, if any.
+ */
+xmlNodePtr xmlGetLastChild(xmlNodePtr parent) {
+    xmlNodePtr last;
+
+    if (parent == NULL) {
+        fprintf(stderr, "xmlGetLastChild : parent == NULL\n");
+	return(NULL);
+    }
+
+    /*
+     * add the new element at the end of the childs list.
+     */
+    if (parent->childs == NULL) {
+        return(NULL);
+    } else {
+        last = parent->childs;
+	while (last->next != NULL) last = last->next;
+    }
+    return(last);
+}
+
+/*
+ * Freeing a node list : Free a node and all its siblings,
+ *                       this is a recursive behaviour, all the childs
+ *                       are freed too.
+ */
+void xmlFreeNodeList(xmlNodePtr cur) {
+    xmlNodePtr next;
+    if (cur == NULL) {
+        fprintf(stderr, "xmlFreeNodeList : node == NULL\n");
+	return;
+    }
+    while (cur != NULL) {
+        next = cur->next;
+        xmlFreeNode(cur);
+	cur = next;
+    }
+}
+
+/*
+ * Freeing a node : this is a recursive behaviour, all the childs
+ *                  are freed too.
+ */
+void xmlFreeNode(xmlNodePtr cur) {
+    if (cur == NULL) {
+        fprintf(stderr, "xmlFreeNode : node == NULL\n");
+	return;
+    }
+    if (cur->properties != NULL) xmlFreePropList(cur->properties);
+    if (cur->childs != NULL) xmlFreeNodeList(cur->childs);
+    if (cur->content != NULL) free(cur->content);
+    if (cur->name != NULL) free((char *) cur->name);
+    if (cur->nsDef != NULL) xmlFreeNsList(cur->nsDef);
+    memset(cur, -1, sizeof(xmlNode));
+    free(cur);
+}
+
+/************************************************************************
+ *									*
+ *		Content access functions				*
+ *									*
+ ************************************************************************/
+ 
+/*
+ * Changing the content of a node.
+ */
+void xmlNodeSetContent(xmlNodePtr cur, const CHAR *content) {
+    if (cur == NULL) {
+        fprintf(stderr, "xmlNodeSetContent : node == NULL\n");
+	return;
+    }
+    if (cur->content != NULL) free(cur->content);
+    if (content != NULL)
+	cur->content = xmlStrdup(content);
+    else 
+	cur->content = NULL;
+}
+
+/*
+ * Changing the content of a node.
+ */
+void xmlNodeSetContentLen(xmlNodePtr cur, const CHAR *content, int len) {
+    if (cur == NULL) {
+        fprintf(stderr, "xmlNodeSetContent : node == NULL\n");
+	return;
+    }
+    if (cur->content != NULL) free(cur->content);
+    if (content != NULL)
+	cur->content = xmlStrndup(content, len);
+    else 
+	cur->content = NULL;
+}
+
+/*
+ * Adding content to a node.
+ */
+void xmlNodeAddContent(xmlNodePtr cur, const CHAR *content) {
+    if (cur == NULL) {
+        fprintf(stderr, "xmlNodeAddContent : node == NULL\n");
+	return;
+    }
+    cur->content = xmlStrcat(cur->content, content);
+}
+
+/*
+ * Adding content to a node.
+ */
+void xmlNodeAddContentLen(xmlNodePtr cur, const CHAR *content, int len) {
+    if (cur == NULL) {
+        fprintf(stderr, "xmlNodeAddContent : node == NULL\n");
+	return;
+    }
+    cur->content = xmlStrncat(cur->content, content, len);
+}
+
+/*
+ * Search a Ns registered under a given name space for a document.
+ *      recurse on the parents until it finds the defined namespace
+ *      or return NULL otherwise.
+ *
+ * Note : nameSpace == NULL is valid, this is a search for the default
+ *        namespace.
+ */
+xmlNsPtr xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const CHAR *nameSpace) {
+    xmlNsPtr cur;
+
+    while (node != NULL) {
+	cur = node->nsDef;
+	while (cur != NULL) {
+	    if ((cur->prefix == NULL) && (nameSpace == NULL))
+	        return(cur);
+	    if ((cur->prefix != NULL) && (nameSpace != NULL) &&
+	        (!xmlStrcmp(cur->prefix, nameSpace)))
+		return(cur);
+	    cur = cur->next;
+	}
+	node = node->parent;
+    }
+    if (doc != NULL) {
+        cur = doc->oldNs;
+	while (cur != NULL) {
+	    if ((cur->prefix != NULL) && (nameSpace != NULL) &&
+	        (!xmlStrcmp(cur->prefix, nameSpace)))
+		return(cur);
+	    cur = cur->next;
+	}
+    }
+    return(NULL);
+}
+
+/*
+ * Search a Ns aliasing a given URI
+ *      recurse on the parents until it finds the defined namespace
+ *      or return NULL otherwise.
+ */
+xmlNsPtr xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node, const CHAR *href) {
+    xmlNsPtr cur;
+
+    while (node != NULL) {
+	cur = node->nsDef;
+	while (cur != NULL) {
+	    if ((cur->href != NULL) && (href != NULL) &&
+	        (!xmlStrcmp(cur->href, href)))
+		return(cur);
+	    cur = cur->next;
+	}
+	node = node->parent;
+    }
+    if (doc != NULL) {
+        cur = doc->oldNs;
+	while (cur != NULL) {
+	    if ((cur->href != NULL) && (href != NULL) &&
+	        (!xmlStrcmp(cur->href, href)))
+		return(cur);
+	    cur = cur->next;
+	}
+    }
+    return(NULL);
+}
+
+/*
+ * Reading the content of a given property.
+ */
+const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name) {
+    xmlAttrPtr prop = node->properties;
+
+    while (prop != NULL) {
+        if (!xmlStrcmp(prop->name, name)) return(prop->value);
+	prop = prop->next;
+    }
+    return(NULL);
+}
+
+/*
+ * Setting the content of a given property.
+ */
+xmlAttrPtr xmlSetProp(xmlNodePtr node, const CHAR *name, const CHAR *value) {
+    xmlAttrPtr prop = node->properties;
+
+    while (prop != NULL) {
+        if (!xmlStrcmp(prop->name, name)) {
+	    if (prop->value != NULL) 
+	        free((char *) prop->value);
+	    prop->value = NULL;
+	    if (value != NULL)
+		prop->value = xmlStrdup(value);
+	    return(prop);
+	}
+	prop = prop->next;
+    }
+    prop = xmlNewProp(node, name, value);
+    return(prop);
+}
+
+/*
+ * Is this node a piece of text
+ */
+int xmlNodeIsText(xmlNodePtr node) {
+    if (node == NULL) return(0);
+
+    if (node->type == XML_TYPE_TEXT) return(1);
+    return(0);
+}
+
+/*
+ * Concat a piece of text to an existing text node
+ *
+ * TODO !!! Should be optimized with a bit of preallocation.
+ */
+void xmlTextConcat(xmlNodePtr node, const CHAR *content, int len) {
+    if (node == NULL) return;
+
+    if (node->type != XML_TYPE_TEXT) {
+	fprintf(stderr, "xmlTextConcat: node is not text\n");
+        return;
+    }
+    node->content = xmlStrncat(node->content, content, len);
+}
+
+/************************************************************************
+ *									*
+ *			Output : to a FILE or in memory			*
+ *									*
+ ************************************************************************/
+
+/*
+ * routine which manage and grows an output buffer. One can write
+ * standard char array's (8 bits char) or CHAR's arrays.
+ */
+static CHAR *buffer = NULL;
+static int buffer_index = 0;
+static int buffer_size = 0;
+
+void xmlBufferWriteCHAR(const CHAR *string) {
+    const CHAR *cur;
+
+    if (buffer == NULL) {
+        buffer_size = 50000;
+        buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
+	if (buffer == NULL) {
+	    fprintf(stderr, "xmlBufferWrite : out of memory!\n");
+	    exit(1);
+	}
+    }
+    
+    if (string == NULL) return;
+    for (cur = string;*cur != 0;cur++) {
+        if (buffer_index  + 10 >= buffer_size) {
+	    buffer_size *= 2;
+	    buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
+	    if (buffer == NULL) {
+	        fprintf(stderr, "xmlBufferWrite : out of memory!\n");
+		exit(1);
+	    }
+	}
+        buffer[buffer_index++] = *cur;
+    }
+    buffer[buffer_index] = 0;
+}
+
+void xmlBufferWriteChar(const char *string) {
+    const char *cur;
+
+    if (buffer == NULL) {
+        buffer_size = 50000;
+        buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
+	if (buffer == NULL) {
+	    fprintf(stderr, "xmlBufferWrite : out of memory!\n");
+	    exit(1);
+	}
+    }
+    
+    if (string == NULL) return;
+    for (cur = string;*cur != 0;cur++) {
+        if (buffer_index  + 10 >= buffer_size) {
+	    buffer_size *= 2;
+	    buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
+	    if (buffer == NULL) {
+	        fprintf(stderr, "xmlBufferWrite : out of memory!\n");
+		exit(1);
+	    }
+	}
+        buffer[buffer_index++] = *cur;
+    }
+    buffer[buffer_index] = 0;
+}
+
+/*
+ * Dump the global Namespace inherited from the old WD.
+ * Within the context of the document header.
+ */
+static void xmlGlobalNsDump(xmlNsPtr cur) {
+    if (cur == NULL) {
+        fprintf(stderr, "xmlGlobalNsDump : Ns == NULL\n");
+	return;
+    }
+    if (cur->type == XML_GLOBAL_NAMESPACE) {
+	xmlBufferWriteChar("<?namespace");
+	if (cur->href != NULL) {
+	    xmlBufferWriteChar(" href=\"");
+	    xmlBufferWriteCHAR(cur->href);
+	    xmlBufferWriteChar("\"");
+	}
+	if (cur->prefix != NULL) {
+	    xmlBufferWriteChar(" AS=\"");
+	    xmlBufferWriteCHAR(cur->prefix);
+	    xmlBufferWriteChar("\"");
+	}
+	xmlBufferWriteChar("?>\n");
+    }
+}
+
+/*
+ * Dump an old global XML Namespace list
+ */
+
+static void xmlGlobalNsListDump(xmlNsPtr cur) {
+    while (cur != NULL) {
+        xmlGlobalNsDump(cur);
+	cur = cur->next;
+    }
+}
+
+/*
+ * Dump a local Namespace definition.
+ * Within the context of an element attributes.
+ */
+static void xmlNsDump(xmlNsPtr cur) {
+    if (cur == NULL) {
+        fprintf(stderr, "xmlNsDump : Ns == NULL\n");
+	return;
+    }
+    if (cur->type == XML_LOCAL_NAMESPACE) {
+        /* Within the context of an element attributes */
+	if (cur->prefix != NULL) {
+	    xmlBufferWriteChar(" xmlns:");
+	    xmlBufferWriteCHAR(cur->prefix);
+	} else
+	    xmlBufferWriteChar(" xmlns");
+	xmlBufferWriteChar("=\"");
+	xmlBufferWriteCHAR(cur->href);
+	xmlBufferWriteChar("\"");
+    }
+}
+
+/*
+ * Dump an XML Namespace list
+ */
+
+static void xmlNsListDump(xmlNsPtr cur) {
+    while (cur != NULL) {
+        xmlNsDump(cur);
+	cur = cur->next;
+    }
+}
+
+/*
+ * Dump an XML DTD
+ */
+
+static void xmlDtdDump(xmlDocPtr doc) {
+    xmlDtdPtr cur = doc->dtd;
+
+    if (cur == NULL) {
+        fprintf(stderr, "xmlDtdDump : DTD == NULL\n");
+	return;
+    }
+    xmlBufferWriteChar("<!DOCTYPE ");
+    xmlBufferWriteCHAR(cur->name);
+    if (cur->ExternalID != NULL) {
+	xmlBufferWriteChar(" PUBLIC \"");
+	xmlBufferWriteCHAR(cur->ExternalID);
+	xmlBufferWriteChar("\" \"");
+	xmlBufferWriteCHAR(cur->SystemID);
+	xmlBufferWriteChar("\"");
+    }  else if (cur->SystemID != NULL) {
+	xmlBufferWriteChar(" SYSTEM \"");
+	xmlBufferWriteCHAR(cur->SystemID);
+	xmlBufferWriteChar("\"");
+    }
+    if ((cur->entities == NULL) && (doc->entities == NULL)) {
+	xmlBufferWriteChar(">\n");
+	return;
+    }
+    xmlBufferWriteChar(" [\n");
+    if (cur->entities != NULL)
+	xmlDumpEntitiesTable((xmlEntitiesTablePtr) cur->entities);
+    if (doc->entities != NULL)
+	xmlDumpEntitiesTable((xmlEntitiesTablePtr) doc->entities);
+    xmlBufferWriteChar("]");
+
+    /* TODO !!! a lot more things to dump ... */
+    xmlBufferWriteChar(">\n");
+}
+
+/*
+ * Dump an XML property
+ */
+
+static void xmlAttrDump(xmlDocPtr doc, xmlAttrPtr cur) {
+    if (cur == NULL) {
+        fprintf(stderr, "xmlAttrDump : property == NULL\n");
+	return;
+    }
+    xmlBufferWriteChar(" ");
+    xmlBufferWriteCHAR(cur->name);
+    if (cur->value) {
+	xmlBufferWriteChar("=\"");
+	xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->value));
+	xmlBufferWriteChar("\"");
+    }
+}
+
+/*
+ * Dump an XML property list
+ */
+
+static void xmlAttrListDump(xmlDocPtr doc, xmlAttrPtr cur) {
+    if (cur == NULL) {
+        fprintf(stderr, "xmlAttrListDump : property == NULL\n");
+	return;
+    }
+    while (cur != NULL) {
+        xmlAttrDump(doc, cur);
+	cur = cur->next;
+    }
+}
+
+/*
+ * Dump an XML node list
+ */
+
+static void xmlNodeDump(xmlDocPtr doc, xmlNodePtr cur, int level);
+static void xmlNodeListDump(xmlDocPtr doc, xmlNodePtr cur, int level) {
+    if (cur == NULL) {
+        fprintf(stderr, "xmlNodeListDump : node == NULL\n");
+	return;
+    }
+    while (cur != NULL) {
+        xmlNodeDump(doc, cur, level);
+	cur = cur->next;
+    }
+}
+
+/*
+ * Dump an XML node
+ */
+
+static void xmlNodeDump(xmlDocPtr doc, xmlNodePtr cur, int level) {
+    int i;
+
+    if (cur == NULL) {
+        fprintf(stderr, "xmlNodeDump : node == NULL\n");
+	return;
+    }
+    if (cur->type == XML_TYPE_TEXT) {
+	if (cur->content != NULL)
+	    xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->content));
+	return;
+    }
+    if (cur->type == XML_TYPE_COMMENT) {
+	if (cur->content != NULL) {
+	    xmlBufferWriteChar("<!--");
+	    xmlBufferWriteCHAR(cur->content);
+	    xmlBufferWriteChar("-->");
+	}
+	return;
+    }
+    if (xmlIndentTreeOutput)
+	for (i = 0;i < level;i++)
+	    xmlBufferWriteChar("  ");
+
+    xmlBufferWriteChar("<");
+    if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+        xmlBufferWriteCHAR(cur->ns->prefix);
+	xmlBufferWriteChar(":");
+    }
+
+    xmlBufferWriteCHAR(cur->name);
+    if (cur->nsDef)
+        xmlNsListDump(cur->nsDef);
+    if (cur->properties != NULL)
+        xmlAttrListDump(doc, cur->properties);
+
+    if ((cur->content == NULL) && (cur->childs == NULL)) {
+        xmlBufferWriteChar("/>\n");
+	return;
+    }
+    xmlBufferWriteChar(">");
+    if (cur->content != NULL)
+	xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->content));
+    if (cur->childs != NULL) {
+	xmlBufferWriteChar("\n");
+	xmlNodeListDump(doc, cur->childs, level + 1);
+	if (xmlIndentTreeOutput)
+	    for (i = 0;i < level;i++)
+		xmlBufferWriteChar("  ");
+    }
+    xmlBufferWriteChar("</");
+    if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+        xmlBufferWriteCHAR(cur->ns->prefix);
+	xmlBufferWriteChar(":");
+    }
+
+    xmlBufferWriteCHAR(cur->name);
+    xmlBufferWriteChar(">\n");
+}
+
+/*
+ * Dump an XML document
+ */
+static void xmlDocContentDump(xmlDocPtr cur) {
+    if (oldXMLWDcompatibility)
+	xmlBufferWriteChar("<?XML version=\"");
+    else 
+	xmlBufferWriteChar("<?xml version=\"");
+    xmlBufferWriteCHAR(cur->version);
+    xmlBufferWriteChar("\"");
+    if (cur->encoding != NULL) {
+        xmlBufferWriteChar(" encoding=\"");
+	xmlBufferWriteCHAR(cur->encoding);
+	xmlBufferWriteChar("\"");
+    }
+    switch (cur->standalone) {
+        case 0:
+	    xmlBufferWriteChar(" standalone=\"no\"");
+	    break;
+        case 1:
+	    xmlBufferWriteChar(" standalone=\"yes\"");
+	    break;
+    }
+    xmlBufferWriteChar("?>\n");
+    if ((cur->dtd != NULL) || (cur->entities != NULL))
+        xmlDtdDump(cur);
+    if (cur->root != NULL) {
+	/* global namespace definitions, the old way */
+	if (oldXMLWDcompatibility)
+	    xmlGlobalNsListDump(cur->oldNs);
+	else 
+	    xmlUpgradeOldNs(cur);
+        xmlNodeDump(cur, cur->root, 0);
+    }
+}
+
+/*
+ * Dump an XML document to memory.
+ */
+
+void xmlDocDumpMemory(xmlDocPtr cur, CHAR**mem, int *size) {
+    if (cur == NULL) {
+        fprintf(stderr, "xmlDocDump : document == NULL\n");
+	*mem = NULL;
+	*size = 0;
+	return;
+    }
+    buffer_index = 0;
+    xmlDocContentDump(cur);
+
+    *mem = buffer;
+    *size = buffer_index;
+}
+
+/*
+ * Dump an XML document to the given FD
+ */
+
+void xmlDocDump(FILE *f, xmlDocPtr cur) {
+    if (cur == NULL) {
+        fprintf(stderr, "xmlDocDump : document == NULL\n");
+	return;
+    }
+    buffer_index = 0;
+    xmlDocContentDump(cur);
+
+    fwrite(buffer, sizeof(CHAR), buffer_index, f);
+}
+
+/************************************************************************
+ *									*
+ *				Debug					*
+ *									*
+ ************************************************************************/
+
+#ifdef STANDALONE
+int main(void) {
+    xmlDocPtr doc;
+    xmlNodePtr tree, subtree;
+    xmlNsPtr ns1;
+    xmlNsPtr ns2;
+
+    /*
+     * build a fake XML document
+     */
+    doc = xmlNewDoc("1.0");
+    ns1 = xmlNewNs(doc, "http://www.ietf.org/standards/dav/", "D");
+    ns2 = xmlNewNs(doc, "http://www.w3.com/standards/z39.50/", "Z");
+    doc->root = xmlNewNode(ns1, "multistatus", NULL);
+    tree = xmlNewChild(doc->root, NULL, "response", NULL);
+    subtree = xmlNewChild(tree, NULL, "prop", NULL);
+    xmlNewChild(subtree, ns2, "Authors", NULL);
+    subtree = xmlNewChild(tree, NULL, "status", "HTTP/1.1 420 Method Failure");
+    tree = xmlNewChild(doc->root, NULL, "response", NULL);
+    subtree = xmlNewChild(tree, NULL, "prop", NULL);
+    xmlNewChild(subtree, ns2, "Copyright-Owner", NULL);
+    subtree = xmlNewChild(tree, NULL, "status", "HTTP/1.1 409 Conflict");
+    tree = xmlNewChild(doc->root, NULL, "responsedescription",
+                       "Copyright Owner can not be deleted or altered");
+
+    /*
+     * print it.
+     */
+    xmlDocDump(stdout, doc);
+
+    /*
+     * free it.
+     */
+    xmlFreeDoc(doc);
+    return(0);
+}
+#endif
diff --git a/tree.h b/tree.h
new file mode 100644
index 0000000..7a48a9b
--- /dev/null
+++ b/tree.h
@@ -0,0 +1,180 @@
+/*
+ * tree.h : describes the structures found in an tree resulting
+ *          from an XML parsing.
+ *
+ * See Copyright for the status of this software.
+ *
+ * $Id$
+ */
+
+#ifndef __XML_TREE_H__
+#define __XML_TREE_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Type definitions
+ */
+#ifdef UNICODE
+typedef unsigned short CHAR;
+#else
+typedef unsigned char CHAR;
+#endif
+
+/*
+ * a DTD Notation definition
+ * TODO !!!!
+ */
+
+/*
+ * a DTD Attribute definition
+ * TODO !!!!
+ */
+
+/*
+ * a DTD Element definition.
+ */
+#define XML_ELEMENT_TYPE_EMPTY		1
+#define XML_ELEMENT_TYPE_ANY		2
+#define XML_ELEMENT_TYPE_MIXED		3
+#define XML_ELEMENT_TYPE_ELEMENT	4
+
+typedef struct xmlElement {
+    const CHAR    *name;	/* Element name */
+    int            type;	/* type (too simple, to extend ...) */
+    /* TODO !!! more needed */
+} xmlElement, *xmlElementPtr;
+
+/*
+ * An XML namespace.
+ * Note that prefix == NULL is valid, it defines the default namespace
+ * within the subtree (until overriden).
+ */
+
+#define XML_GLOBAL_NAMESPACE		1 /* old style global namespace */
+#define XML_LOCAL_NAMESPACE		2 /* new style local scoping */
+
+typedef struct xmlNs {
+    struct xmlNs  *next;	/* next Ns link for this node  */
+    int            type;	/* global or local */
+    const CHAR    *href;	/* URL for the namespace */
+    const CHAR    *prefix;	/* prefix for the namespace */
+} xmlNs, *xmlNsPtr;
+
+/*
+ * An XML DtD, as defined by <!DOCTYPE.
+ */
+typedef struct xmlDtd {
+    const CHAR    *name;	/* Name of the DTD */
+    const CHAR    *ExternalID;	/* External identifier for PUBLIC DTD */
+    const CHAR    *SystemID;	/* URI for a SYSTEM or PUBLIC DTD */
+    void          *elements;    /* Hash table for elements if any */
+    void          *entities;    /* Hash table for entities if any */
+    /* struct xmlDtd *next;	 * next  link for this document  */
+} xmlDtd, *xmlDtdPtr;
+
+/*
+ * A attribute of an XML node.
+ */
+typedef struct xmlAttr {
+    struct xmlNode *node;	/* attr->node link */
+    struct xmlAttr *next;	/* parent->childs link */
+    const CHAR     *name;       /* the name of the property */
+    const CHAR     *value;      /* the value of the property */
+} xmlAttr, *xmlAttrPtr;
+
+/*
+ * A node in an XML tree.
+ */
+#define XML_TYPE_TEXT		1
+#define XML_TYPE_COMMENT	2
+#define XML_TYPE_ENTITY		3
+
+typedef struct xmlNode {
+    struct xmlNode *parent;	/* child->parent link */
+    struct xmlNode *next;	/* next sibling link  */
+    struct xmlNode *childs;	/* parent->childs link */
+    struct xmlAttr *properties;	/* properties list */
+    int             type;	/* type number in the DTD */
+    const CHAR     *name;       /* the name of the node, or the entity */
+    xmlNs          *ns;         /* pointer to the associated namespace */
+    xmlNs          *nsDef;      /* namespace definitions on this node */
+    CHAR           *content;    /* the content */
+} xmlNode, *xmlNodePtr;
+
+/*
+ * An XML document.
+ */
+typedef struct xmlDoc {
+    char           *name;	/* name/filename/URI of the document */
+    const CHAR     *version;	/* the XML version string */
+    const CHAR     *encoding;   /* encoding, if any */
+    int             standalone; /* standalone document (no external refs) */
+    struct xmlDtd  *dtd;	/* the document DTD if available */
+    struct xmlNs   *oldNs;	/* Global namespace, the old way */
+    void          *entities;    /* Hash table for general entities if any */
+    struct xmlNode *root;	/* the document tree */
+} xmlDoc, *xmlDocPtr;
+
+/*
+ * Variables.
+ */
+extern xmlNsPtr baseDTD;
+extern int oldXMLWDcompatibility;/* maintain compatibility with old WD */
+extern int xmlIndentTreeOutput;  /* try to indent the tree dumps */
+
+/*
+ * Functions.
+ */
+extern xmlDtdPtr xmlNewDtd(xmlDocPtr doc, const CHAR *name,
+                    const CHAR *ExternalID, const CHAR *SystemID);
+extern void xmlFreeDtd(xmlDtdPtr cur);
+extern xmlNsPtr xmlNewGlobalNs(xmlDocPtr doc, const CHAR *href, const CHAR *AS);
+extern xmlNsPtr xmlNewNs(xmlNodePtr node, const CHAR *href, const CHAR *AS);
+extern void xmlFreeNs(xmlNsPtr cur);
+extern xmlDocPtr xmlNewDoc(const CHAR *version);
+extern void xmlFreeDoc(xmlDocPtr cur);
+extern xmlAttrPtr xmlNewProp(xmlNodePtr node, const CHAR *name,
+                             const CHAR *value);
+extern xmlAttrPtr xmlSetProp(xmlNodePtr node, const CHAR *name,
+                             const CHAR *value);
+extern const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name);
+extern void xmlFreePropList(xmlAttrPtr cur);
+extern void xmlFreeProp(xmlAttrPtr cur);
+extern xmlNodePtr xmlNewNode(xmlNsPtr ns, const CHAR *name, CHAR *content);
+extern xmlNodePtr xmlNewText(const CHAR *content);
+extern xmlNodePtr xmlNewTextLen(const CHAR *content, int len);
+extern xmlNodePtr xmlNewComment(CHAR *content);
+extern xmlNodePtr xmlAddChild(xmlNodePtr parent, xmlNodePtr cur);
+extern xmlNodePtr xmlGetLastChild(xmlNodePtr node);
+extern int xmlNodeIsText(xmlNodePtr node);
+extern void xmlTextConcat(xmlNodePtr node, const CHAR *content, int len);
+extern void xmlFreeNodeList(xmlNodePtr cur);
+extern void xmlFreeNode(xmlNodePtr cur);
+extern void xmlNodeSetContent(xmlNodePtr cur, const CHAR *content);
+extern void xmlNodeSetContentLen(xmlNodePtr cur, const CHAR *content, int len);
+extern void xmlNodeAddContent(xmlNodePtr cur, const CHAR *content);
+extern void xmlNodeAddContentLen(xmlNodePtr cur, const CHAR *content, int len);
+extern xmlNsPtr xmlSearchNs(xmlDocPtr doc, xmlNodePtr node,
+                            const CHAR *nameSpace);
+extern xmlNsPtr xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node,
+                                  const CHAR *href);
+extern void xmlSetNs(xmlNodePtr node, xmlNsPtr ns);
+extern xmlNodePtr xmlNewChild(xmlNodePtr parent, xmlNsPtr ns,
+                              const CHAR *name, CHAR *content);
+
+extern void xmlDocDumpMemory(xmlDocPtr cur, CHAR**mem, int *size);
+extern void xmlDocDump(FILE *f, xmlDocPtr doc);
+extern void xmlBufferWriteCHAR(const CHAR *string);
+extern void xmlBufferWriteChar(const char *string);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_TREE_H__ */
+
diff --git a/xml_entities.c b/xml_entities.c
deleted file mode 100644
index 3c9d55c..0000000
--- a/xml_entities.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * entities.c : implementation for the XML entities handking
- *
- * See Copyright for the status of this software.
- *
- * $Id$
- */
-
-#include <stdio.h>
-#include <malloc.h>
-#include <strings.h>
-#include "xml_entities.h"
-
-/*
- * A buffer used for converting entities to their equivalent and back.
- */
-static CHAR *buffer = NULL;
-static int buffer_size = 0;
-
-void growBuffer(void) {
-    buffer_size *= 2;
-    buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
-    if (buffer == NULL) {
-	perror("realloc failed");
-	exit(1);
-    }
-}
-
-/*
- * xmlFreeEntity : clean-up an entity record.
- */
-
-void xmlFreeEntity(xmlEntityPtr entity) {
-    if (entity == NULL) return;
-
-    if (entity->value != NULL) free(entity->value);
-    entity->value = NULL;
-    if (entity->id != NULL)
-	free((char *) entity->id);
-}
-
-/*
- * xmlAddDocEntity : register a new entity for an entities table.
- */
-static void xmlAddEntity(xmlEntitiesTablePtr table, CHAR *value,
-                         const CHAR *id) {
-    int i;
-    xmlEntityPtr cur;
-
-    for (i = 0;i < table->nb_entities;i++) {
-        cur = &table->table[i];
-	if (!xmlStrcmp(cur->id, id)) {
-	    free(cur->value);
-	    cur->value = xmlStrdup(value);
-	}
-    }
-    if (table->nb_entities >= table->max_entities) {
-        /*
-	 * need more elements.
-	 */
-	table->max_entities *= 2;
-	table->table = (xmlEntityPtr) 
-	    realloc(table->table, table->max_entities * sizeof(xmlEntity));
-	if (table->table) {
-	    perror("realloc failed");
-	    exit(1);
-	}
-    }
-    cur = &table->table[table->nb_entities];
-    cur->value = xmlStrdup(value);
-    cur->id = xmlStrdup(id);
-    table->nb_entities++;
-}
-
-
-/*
- * xmlAddDtdEntity : register a new entity for this document.
- */
-void xmlAddDtdEntity(xmlDtdPtr dtd, CHAR *value, const CHAR *id) {
-    xmlEntitiesTablePtr table;
-
-    table = (xmlEntitiesTablePtr) dtd->entities;
-    if (table == NULL) {
-        table = xmlCreateEntitiesTable();
-	dtd->entities = table;
-    }
-    xmlAddEntity(table, value, id);
-}
-
-/*
- * xmlAddDocEntity : register a new entity for this document.
- */
-void xmlAddDocEntity(xmlDocPtr doc, CHAR *value, const CHAR *id) {
-    xmlEntitiesTablePtr table;
-
-    table = (xmlEntitiesTablePtr) doc->entities;
-    if (table == NULL) {
-        table = xmlCreateEntitiesTable();
-	doc->entities = table;
-    }
-    xmlAddEntity(table, value, id);
-}
-
-/*
- * xmlGetEntity : do an entity lookup in the hash table and
- *       returns the corrsponding CHAR *, if found, zero otherwise.
- */
-CHAR *xmlGetEntity(xmlDocPtr doc, const CHAR *id) {
-    int i;
-    xmlEntityPtr cur;
-    xmlEntitiesTablePtr table;
-
-    if (doc->entities == NULL) return(0);
-    table = (xmlEntitiesTablePtr) doc->entities;
-    for (i = 0;i < table->nb_entities;i++) {
-        cur = &table->table[i];
-	if (!xmlStrcmp(cur->id, id)) return(cur->value);
-    }
-    return(NULL);
-}
-
-/*
- * xmlReadEntities : read an entity.
- */
-const CHAR *xmlReadEntity(xmlDocPtr doc, const CHAR **input) {
-    static CHAR *entity = NULL;
-    static int entity_size = 100;
-    const CHAR *cur = *input;
-
-    if (entity == NULL) {
-        entity = (CHAR *) malloc(entity_size * sizeof(CHAR));
-	if (entity == NULL) {
-	    fprintf(stderr, "xmlReadEntity : cannot allocate %d bytes\n",
-	            entity_size * sizeof(CHAR));
-            return(NULL);
-	}
-    }
-    if (*cur == '&') {
-        cur++;
-	if (*cur == '#') {
-	    /* TODO !!!! 
-	    fprintf(stderr, "Character reference not yet implemented\n"); */
-	} else {
-	    /* TODO !!!! 
-	    fprintf(stderr, "Entity search not yet implemented\n"); */
-	}
-    }
-
-    /*
-     * The few predefined entities.
-     */
-    if ((cur[0] == 'a') && (cur[1] == 'm') && (cur[2] == 'p') &&
-        (cur[3] == ';')) {
-        entity[0] = '%';
-        entity[1] = 0;
-	cur += 3;
-	*input = cur;
-        return(entity);
-    } else if ((cur[0] == 'q') && (cur[1] == 'u') && (cur[2] == 'o') &&
-        (cur[3] == 't') && (cur[4] == ';')) {
-        entity[0] = '"';
-        entity[1] = 0;
-	cur += 4;
-	*input = cur;
-        return(entity);
-    } else if ((cur[0] == 'a') && (cur[1] == 'p') && (cur[2] == 'o') &&
-        (cur[3] == 's') && (cur[4] == ';')) {
-        entity[0] = '\'';
-        entity[1] = 0;
-	cur += 4;
-	*input = cur;
-        return(entity);
-    } else if ((cur[0] == 'l') && (cur[1] == 't') && (cur[2] == ';')) {
-        entity[0] = '<';
-        entity[1] = 0;
-	cur += 2;
-	*input = cur;
-        return(entity);
-    } else if ((cur[0] == 'g') && (cur[1] == 't') && (cur[2] == ';')) {
-        entity[0] = '>';
-        entity[1] = 0;
-	cur += 2;
-	*input = cur;
-        return(entity);
-    }
-
-    return(NULL);
-}
-
-/*
- * xmlDecodeEntities : do a global entities lookup on a input string
- *        and returns a duplicate after the entities substitution.
- */
-CHAR *xmlDecodeEntities(xmlDocPtr doc, const CHAR *input, int len) {
-    const CHAR *cur = input;
-    CHAR *out = buffer;
-    int i;
-
-    if (buffer == NULL) {
-        buffer_size = 1000;
-        buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
-	if (buffer == NULL) {
-	    perror("malloc failed");
-            exit(1);
-	}
-	out = buffer;
-    }
-    for (i = 0;(*cur != 0) && (cur - input < len);cur++) {
-        if (*cur == '&') {
-            const CHAR *entity = xmlReadEntity(doc, &cur);
-	    if (entity != NULL)
-	        while (*entity != 0) { 
-		    *out++ = *entity++;
-		    i++;
-		    if (i + 10 > buffer_size) {
-			int index = out - buffer;
-
-			growBuffer();
-			out = &buffer[index];
-		    }
-		}
-	} else if (*cur == '%') {
-	    /* TODO !!!!!
-	    fprintf(stderr, " \n"); */
-	} else {
-	    *out++ = *cur;
-	    i++;
-	}
-
-	if (i + 10 > buffer_size) {
-	    int index = out - buffer;
-
-	    growBuffer();
-	    out = &buffer[index];
-	}
-    }
-    *out++ = 0;
-    return(buffer);
-}
-
-/*
- * xmlEncodeEntities : do a global encoding of a string, replacing the
- *                     basic values with their entities form.
- */
-CHAR *xmlEncodeEntities(xmlDocPtr doc, const CHAR *input) {
-    const CHAR *cur = input;
-    CHAR *out = buffer;
-
-    if (buffer == NULL) {
-        buffer_size = 1000;
-        buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
-	if (buffer == NULL) {
-	    perror("malloc failed");
-            exit(1);
-	}
-	out = buffer;
-    }
-    while (*cur != '\0') {
-        if (out - buffer > buffer_size - 100) {
-	    int index = out - buffer;
-
-	    growBuffer();
-	    out = &buffer[index];
-	}
-
-	/*
-	 * By default one have to encode at least '<', '>', '"' and '&' !
-	 * One could try a better encoding using the entities defined and
-	 * used as a compression code !!!.
-	 */
-	if (*cur == '<') {
-	    *out++ = '&';
-	    *out++ = 'l';
-	    *out++ = 't';
-	    *out++ = ';';
-	} else if (*cur == '>') {
-	    *out++ = '&';
-	    *out++ = 'g';
-	    *out++ = 't';
-	    *out++ = ';';
-	} else if (*cur == '&') {
-	    *out++ = '&';
-	    *out++ = 'a';
-	    *out++ = 'm';
-	    *out++ = 'p';
-	    *out++ = ';';
-	} else if (*cur == '"') {
-	    *out++ = '&';
-	    *out++ = 'q';
-	    *out++ = 'u';
-	    *out++ = 'o';
-	    *out++ = 't';
-	    *out++ = ';';
-	} else if (*cur == '\'') {
-	    *out++ = '&';
-	    *out++ = 'a';
-	    *out++ = 'p';
-	    *out++ = 'o';
-	    *out++ = 's';
-	    *out++ = ';';
-	} else {
-	    /*
-	     * default case, just copy !
-	     */
-	    *out++ = *cur;
-	}
-	cur++;
-    }
-    *out++ = 0;
-    return(buffer);
-}
-
-/*
- * xmlCreateEntitiesTable : create and initialize an enmpty hash table
- */
-xmlEntitiesTablePtr xmlCreateEntitiesTable(void) {
-    xmlEntitiesTablePtr ret;
-
-    ret = (xmlEntitiesTablePtr) 
-         malloc(sizeof(xmlEntitiesTable));
-    if (ret == NULL) {
-        fprintf(stderr, "xmlCreateEntitiesTable : malloc(%d) failed\n",
-	        sizeof(xmlEntitiesTable));
-        return(NULL);
-    }
-    ret->max_entities = XML_MIN_ENTITIES_TABLE;
-    ret->nb_entities = 0;
-    ret->table = (xmlEntityPtr ) 
-         malloc(ret->max_entities * sizeof(xmlEntity));
-    if (ret == NULL) {
-        fprintf(stderr, "xmlCreateEntitiesTable : malloc(%d) failed\n",
-	        ret->max_entities * sizeof(xmlEntity));
-	free(ret);
-        return(NULL);
-    }
-    return(ret);
-}
-
-/*
- * xmlFreeEntitiesTable : clean up and free an entities hash table.
- */
-void xmlFreeEntitiesTable(xmlEntitiesTablePtr table) {
-    int i;
-
-    if (table == NULL) return;
-
-    for (i = 0;i < table->nb_entities;i++) {
-        xmlFreeEntity(&table->table[i]);
-    }
-    free(table->table);
-    free(table);
-}
-
diff --git a/xml_entities.h b/xml_entities.h
deleted file mode 100644
index a0b24ac..0000000
--- a/xml_entities.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * entities.h : interface for the XML entities handking
- *
- * See Copyright for the status of this software.
- *
- * $Id$
- */
-
-#ifndef __XML_ENTITIES_H__
-#define __XML_ENTITIES_H__
-#include "xml_parser.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * An unit of storage for an entity, contains the string, the value
- * and the linkind data needed for the linking in the hash table.
- */
-
-typedef struct xmlEntity {
-    const CHAR *id;		/* The entity name */
-    CHAR *value;		/* The entity CHAR equivalent */
-} xmlEntity, *xmlEntityPtr;
-
-/*
- * ALl entities are stored in a table there is one table per DTD
- * and one extra per document.
- */
-
-#define XML_MIN_ENTITIES_TABLE	32
-
-typedef struct xmlEntitiesTable {
-    int nb_entities;		/* number of elements stored */
-    int max_entities;		/* maximum number of elements */
-    xmlEntityPtr table;		/* the table of entities */
-} xmlEntitiesTable, *xmlEntitiesTablePtr;
-
-/*
- * External functions :
- */
-
-extern void xmlAddDocEntity(xmlDocPtr doc, CHAR *value, const CHAR *id);
-extern void xmlAddDtdEntity(xmlDtdPtr dtd, CHAR *value, const CHAR *id);
-extern CHAR *xmlGetEntity(xmlDocPtr doc, const CHAR *id);
-extern CHAR *xmlSubstituteEntities(xmlDocPtr doc, const CHAR *input);
-extern CHAR *xmlEncodeEntities(xmlDocPtr doc, const CHAR *input);
-extern CHAR *xmlDecodeEntities(xmlDocPtr doc, const CHAR *input, int len);
-extern xmlEntitiesTablePtr xmlCreateEntitiesTable(void);
-extern void xmlFreeEntitiesTable(xmlEntitiesTablePtr table);
-
-#ifdef __cplusplus
-}
-#endif
-
-# endif /* __XML_ENTITIES_H__ */
diff --git a/xml_parser.c b/xml_parser.c
deleted file mode 100644
index dfec5a7..0000000
--- a/xml_parser.c
+++ /dev/null
@@ -1,1183 +0,0 @@
-/*
- * parser.c : an XML 1.0 non-verifying parser
- *
- * See Copyright for the status of this software.
- *
- * $Id$
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h> /* for memset() only */
-#include <malloc.h>
-#include <sys/stat.h>
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-#include "xml_tree.h"
-#include "xml_parser.h"
-#include "xml_entities.h"
-
-/*
- * A few macros needed to help building the parser.
- */
-
-#ifdef UNICODE
-/*
- * UNICODE version of the macros. Incomplete now TODO !!!!
- */
-#define IS_CHAR(c)							\
-    (((c) == 0x09) || ((c) == 0x0a) || ((c) == 0x0d) ||			\
-     (((c) >= 0x20) && ((c) != 0xFFFE) && ((c) != 0xFFFF)))
-
-#define SKIP_BLANKS(p) 							\
-    while ((*(p) == 0x20) || (*(p) == 0x09) || (*(p) == 0xa) ||		\
-           (*(p) == 0x3000)) (p)++;
-
-/* I'm too lazy to complete this one TODO !!!! */
-#define IS_BASECHAR(c)							\
-    ((((c) >= 0x41) && ((c) <= 0x5a)) ||				\		
-     (((c) >= 0x61) && ((c) <= 0x7a)) ||				\
-     (((c) >= 0xaa) && ((c) <= 0x5b)) ||				\
-     (((c) >= 0xc0) && ((c) <= 0xd6)) ||				\
-     (((c) >= 0xd8) && ((c) <= 0xf6)) ||				\
-     (((c) >= 0xf8) && ((c) <= 0xff)) ||				\
-      ((c) == 0xba))
-
-/* I'm too lazy to complete this one TODO !!!! */
-#define IS_DIGIT(c) (((c) >= 0x30) && ((c) <= 0x39))
-
-/* I'm too lazy to complete this one TODO !!!! */
-#define IS_COMBINING(c) 0
-
-#define IS_IGNORABLE(c)							\
-    ((((c) >= 0x200c) && ((c) <= 0x200f)) ||				\
-     (((c) >= 0x202a) && ((c) <= 0x202e)) ||				\
-     (((c) >= 0x206a) && ((c) <= 0x206f)) ||				\
-      ((c) == 0xfeff))
-
-#define IS_EXTENDER(c)							\
-    (((c) == 0xb7) || ((c) == 0x2d0) || ((c) == 0x2d1) ||		\
-     ((c) == 0x387) || ((c) == 0x640) || ((c) == 0xe46) ||		\
-     ((c) == 0xec6) || ((c) == 0x3005)					\
-     (((c) >= 0x3031) && ((c) <= 0x3035)) ||				\
-     (((c) >= 0x309b) && ((c) <= 0x309e)) ||				\
-     (((c) >= 0x30fc) && ((c) <= 0x30fe)) ||				\
-     (((c) >= 0xff70) && ((c) <= 0xff9e)) ||				\
-      ((c) == 0xff9f))
-
-#define IS_IDEOGRAPHIC(c)						\
-    ((((c) >= 0x4e00) && ((c) <= 0x9fa5)) ||				\
-     (((c) >= 0xf900) && ((c) <= 0xfa2d)) ||				\
-     (((c) >= 0x3021) && ((c) <= 0x3029)) ||				\
-      ((c) == 0x3007))
-
-#define IS_LETTER(c) (IS_BASECHAR(c) || IS_IDEOGRAPHIC(c))
-
-/* I'm too lazy to complete this one ! */
-#define IS_BLANK(c) (((c) == 0x20) || ((c) == 0x09) || ((c) == 0xa))
-#else
-/*
- * 8bits / ASCII version of the macros.
- */
-#define IS_CHAR(c)							\
-    (((c) == 0x09) || ((c) == 0x0a) || ((c) == 0x0d) || ((c) >= 0x20))
-
-#define IS_BASECHAR(c)							\
-    ((((c) >= 0x41) && ((c) <= 0x5a)) ||				\
-     (((c) >= 0x61) && ((c) <= 0x7a)) ||				\
-     (((c) >= 0xaa) && ((c) <= 0x5b)) ||				\
-     (((c) >= 0xc0) && ((c) <= 0xd6)) ||				\
-     (((c) >= 0xd8) && ((c) <= 0xf6)) ||				\
-     (((c) >= 0xf8) && ((c) <= 0xff)) ||				\
-      ((c) == 0xba))
-
-#define IS_DIGIT(c) (((c) >= 0x30) && ((c) <= 0x39))
-
-#define IS_LETTER(c) IS_BASECHAR(c)
-
-#define IS_COMBINING(c) 0
-
-#define IS_IGNORABLE(c) 0
-
-#define IS_EXTENDER(c) ((c) == 0xb7)
-
-#define IS_BLANK(c) (((c) == 0x20) || ((c) == 0x09) || ((c) == 0xa))
-#endif
-
-
-#define SKIP_EOL(p) 							\
-    if (*(p) == 0x13) { p++ ; if (*(p) == 0x10) p++; }			\
-    if (*(p) == 0x10) { p++ ; if (*(p) == 0x13) p++; }
-
-#define SKIP_BLANKS(p) 							\
-    while (IS_BLANK(*(p))) (p)++;
-
-#define MOVETO_ENDTAG(p)						\
-    while (IS_CHAR(*p) && (*(p) != '>')) (p)++;
-
-#define MOVETO_STARTTAG(p)						\
-    while (IS_CHAR(*p) && (*(p) != '<')) (p)++;
-
-/*
- * Forward definition for recusive behaviour.
- */
-xmlNodePtr xmlParseElement(xmlParserCtxtPtr ctxt);
-
-/*
- * xmlHandleData : this routine represent's the specific application
- *    behaviour when reading a piece of text.
- *
- * For example in WebDav, any piece made only of blanks is eliminated
- */
-
-CHAR *xmlHandleData(CHAR *in) {
-    CHAR *cur;
-
-    if (in == NULL) return(NULL);
-    cur = in;
-    while (IS_CHAR(*cur)) {
-        if (!IS_BLANK(*cur)) goto not_blank;
-	cur++;
-    }
-    free(in);
-    return(NULL);
-
-not_blank:
-    return(in);
-}
-
-/*
- * xmlStrndup : a strdup for array of CHAR's
- */
-
-CHAR *xmlStrndup(const CHAR *cur, int len) {
-    CHAR *ret = malloc((len + 1) * sizeof(CHAR));
-
-    if (ret == NULL) {
-        fprintf(stderr, "malloc of %d byte failed\n",
-	        (len + 1) * sizeof(CHAR));
-        return(NULL);
-    }
-    memcpy(ret, cur, len * sizeof(CHAR));
-    ret[len] = 0;
-    return(ret);
-}
-
-/*
- * xmlStrdup : a strdup for CHAR's
- */
-
-CHAR *xmlStrdup(const CHAR *cur) {
-    const CHAR *p = cur;
-
-    while (IS_CHAR(*p)) p++;
-    return(xmlStrndup(cur, p - cur));
-}
-
-/*
- * xmlStrcmp : a strcmp for CHAR's
- */
-
-int xmlStrcmp(const CHAR *str1, const CHAR *str2) {
-    register int tmp;
-
-    do {
-        tmp = *str1++ - *str2++;
-	if (tmp != 0) return(tmp);
-    } while ((*str1 != 0) && (*str2 != 0));
-    return (*str1 - *str2);
-}
-
-/*
- * xmlStrncmp : a strncmp for CHAR's
- */
-
-int xmlStrncmp(const CHAR *str1, const CHAR *str2, int len) {
-    register int tmp;
-
-    if (len <= 0) return(0);
-    do {
-        tmp = *str1++ - *str2++;
-	if (tmp != 0) return(tmp);
-	len--;
-        if (len <= 0) return(0);
-    } while ((*str1 != 0) && (*str2 != 0));
-    return (*str1 - *str2);
-}
-
-/*
- * xmlStrchr : a strchr for CHAR's
- */
-
-CHAR *xmlStrchr(const CHAR *str, CHAR val) {
-    while (*str != 0) {
-        if (*str == val) return((CHAR *) str);
-	str++;
-    }
-    return(NULL);
-}
-
-/*
- * xmlParseName : parse an XML name.
- */
-
-CHAR *xmlParseName(xmlParserCtxtPtr ctxt) {
-    const CHAR *q;
-    CHAR *ret = NULL;
-
-    /*
-     * Name ::= (Letter | '_') (NameChar)*
-     */
-    if (!IS_LETTER(ctxt->cur[0]) && (ctxt->cur[0] != '_')) return(NULL);
-    q = ctxt->cur++;
-    while ((IS_LETTER(ctxt->cur[0])) || (IS_DIGIT(ctxt->cur[0])) ||
-           (ctxt->cur[0] == '.') || (ctxt->cur[0] == '-') || (ctxt->cur[0] == '_') ||
-	   (ctxt->cur[0] == ':') || 
-	   (IS_COMBINING(ctxt->cur[0])) || (IS_IGNORABLE(ctxt->cur[0])) ||
-	   (IS_EXTENDER(ctxt->cur[0])))
-	ctxt->cur++;
-    
-    ret = xmlStrndup(q, ctxt->cur - q);
-
-    return(ret);
-}
-
-/*
- * Parse and return a string between quotes or doublequotes
- */
-CHAR *xmlParseQuotedString(xmlParserCtxtPtr ctxt) {
-    CHAR *ret = NULL;
-    const CHAR *q;
-
-    if (ctxt->cur[0] == '"') {
-        ctxt->cur++;
-	q = ctxt->cur;
-	while (IS_CHAR(ctxt->cur[0]) && (ctxt->cur[0] != '"')) ctxt->cur++;
-	if (ctxt->cur[0] != '"')
-	    fprintf(stderr, "String not closed \"%.50s\n", q);
-        else {
-            ret = xmlStrndup(q, ctxt->cur - q);
-	    ctxt->cur++;
-	}
-    } else if (ctxt->cur[0] == '\''){
-        ctxt->cur++;
-	q = ctxt->cur;
-	while (IS_CHAR(ctxt->cur[0]) && (ctxt->cur[0] != '\'')) ctxt->cur++;
-	if (ctxt->cur[0] != '\'')
-	    fprintf(stderr, "String not closed '%.50s\n", q);
-        else {
-            ret = xmlStrndup(q, ctxt->cur - q);
-	    ctxt->cur++;
-	}
-    }
-    return(ret);
-}
-
-/*
- * Skip an XML (SGML) comment <!-- .... -->
- *
- * TODO !!!! Save the comment in the tree !!!
- */
-void xmlParserSkipComment(xmlParserCtxtPtr ctxt) {
-    const CHAR *q, *start;
-    const CHAR *r;
-
-    /*
-     * An extra check may avoid errors and isn't that costly !
-     */
-    if ((ctxt->cur[0] != '<') || (ctxt->cur[1] != '!') ||
-        (ctxt->cur[2] != '-') || (ctxt->cur[3] != '-')) return;
-
-    ctxt->cur += 4;
-    start = q = ctxt->cur;
-    ctxt->cur++;
-    r = ctxt->cur;
-    ctxt->cur++;
-    while (IS_CHAR(ctxt->cur[0]) &&
-           ((ctxt->cur[0] == ':') || (ctxt->cur[0] != '>') ||
-	    (*r != '-') || (*q != '-'))) {
-        ctxt->cur++;r++;q++;
-    }
-    if (!IS_CHAR(ctxt->cur[0])) {
-        fprintf(stderr, "Comment not terminated <!--%.50s\n", start);
-	ctxt->cur = start; /* !!! We shouldn't really try to recover !!! */
-    } else {
-        ctxt->cur++;
-    }
-}
-
-/*
- * xmlParseNamespace: parse specific '<?namespace ...' constructs.
- */
-
-void xmlParseNamespace(xmlParserCtxtPtr ctxt) {
-    CHAR *href = NULL;
-    CHAR *AS = NULL;
-    int garbage = 0;
-
-    /*
-     * We just skipped "namespace" or "xml:namespace"
-     */
-    SKIP_BLANKS(ctxt->cur);
-
-    while (IS_CHAR(ctxt->cur[0]) && (ctxt->cur[0] != '>')) {
-	/*
-	 * We can have "ns" or "prefix" attributes
-	 * Old encoding as 'href' or 'AS' attributes is still supported
-	 */
-	if ((ctxt->cur[0] == 'n') && (ctxt->cur[1] == 's')) {
-	    garbage = 0;
-	    ctxt->cur += 2;
-	    SKIP_BLANKS(ctxt->cur);
-
-	    if (ctxt->cur[0] != '=') continue;
-	    ctxt->cur++;
-	    SKIP_BLANKS(ctxt->cur);
-
-	    href = xmlParseQuotedString(ctxt);
-	    SKIP_BLANKS(ctxt->cur);
-	} else if ((ctxt->cur[0] == 'h') && (ctxt->cur[1] == 'r') &&
-	    (ctxt->cur[2] == 'e') && (ctxt->cur[3] == 'f')) {
-	    garbage = 0;
-	    ctxt->cur += 4;
-	    SKIP_BLANKS(ctxt->cur);
-
-	    if (ctxt->cur[0] != '=') continue;
-	    ctxt->cur++;
-	    SKIP_BLANKS(ctxt->cur);
-
-	    href = xmlParseQuotedString(ctxt);
-	    SKIP_BLANKS(ctxt->cur);
-	} else if ((ctxt->cur[0] == 'p') && (ctxt->cur[1] == 'r') &&
-	           (ctxt->cur[2] == 'e') && (ctxt->cur[3] == 'f') &&
-	           (ctxt->cur[4] == 'i') && (ctxt->cur[5] == 'x')) {
-	    garbage = 0;
-	    ctxt->cur += 6;
-	    SKIP_BLANKS(ctxt->cur);
-
-	    if (ctxt->cur[0] != '=') continue;
-	    ctxt->cur++;
-	    SKIP_BLANKS(ctxt->cur);
-
-	    AS = xmlParseQuotedString(ctxt);
-	    SKIP_BLANKS(ctxt->cur);
-	} else if ((ctxt->cur[0] == 'A') && (ctxt->cur[1] == 'S')) {
-	    garbage = 0;
-	    ctxt->cur += 2;
-	    SKIP_BLANKS(ctxt->cur);
-
-	    if (ctxt->cur[0] != '=') continue;
-	    ctxt->cur++;
-	    SKIP_BLANKS(ctxt->cur);
-
-	    AS = xmlParseQuotedString(ctxt);
-	    SKIP_BLANKS(ctxt->cur);
-	} else if ((ctxt->cur[0] == '?') && (ctxt->cur[1] == '>')) {
-	    garbage = 0;
-	    ctxt->cur ++;
-	} else {
-            /*
-	     * Found garbage when parsing the namespace
-	     */
-	    if (!garbage) fprintf(stderr,
-	          "\nxmlParseNamespace found garbage: ");
-            fprintf(stderr, "%c", ctxt->cur[0]);
-            ctxt->cur++;
-        }
-    }
-
-    MOVETO_ENDTAG(ctxt->cur);
-    ctxt->cur++;
-
-    /*
-     * Register the DTD.
-     */
-    if (href != NULL)
-        xmlNewDtd(ctxt->doc, href, AS);
-
-    if (AS != NULL) free(AS);
-    if (href != NULL) free(href);
-}
-
-/*
- * xmlParsePI: parse an XML Processing Instruction.
- */
-
-void xmlParsePI(xmlParserCtxtPtr ctxt) {
-    if ((ctxt->cur[0] == '<') && (ctxt->cur[1] == '?')) {
-	/*
-	 * this is a Processing Instruction.
-	 */
-	ctxt->cur += 2;
-
-	/*
-	 * Special for WebDav, support for the Processing Instruction
-	 * '<?namespace ...' contruct in the header of the XML document.
-	 */
-	if ((ctxt->cur[0] == 'n') && (ctxt->cur[1] == 'a') &&
-	    (ctxt->cur[2] == 'm') && (ctxt->cur[3] == 'e') &&
-	    (ctxt->cur[4] == 's') && (ctxt->cur[5] == 'p') &&
-	    (ctxt->cur[6] == 'a') && (ctxt->cur[7] == 'c') &&
-	    (ctxt->cur[8] == 'e')) {
-	    ctxt->cur += 9;
-	    xmlParseNamespace(ctxt);
-	} else if ((ctxt->cur[0] == 'x') && (ctxt->cur[1] == 'm') &&
-	           (ctxt->cur[2] == 'l') && (ctxt->cur[3] == ':') &&
-	           (ctxt->cur[4] == 'n') && (ctxt->cur[5] == 'a') &&
-	           (ctxt->cur[6] == 'm') && (ctxt->cur[7] == 'e') &&
-	           (ctxt->cur[8] == 's') && (ctxt->cur[9] == 'p') &&
-	           (ctxt->cur[10] == 'a') && (ctxt->cur[11] == 'c') &&
-	           (ctxt->cur[12] == 'e')) {
-	    ctxt->cur += 13;
-	    xmlParseNamespace(ctxt);
-	} else {
-	    /* Unknown PI, ignore it ! */
-	    fprintf(stderr, "xmlParsePI : skipping unknown PI %30s\n",
-	            ctxt->cur);
-	    MOVETO_ENDTAG(ctxt->cur);
-	    ctxt->cur++;
-	}
-    }
-}
-
-/*
- * xmlParseAttribute: parse a start of tag.
- *
- * Attribute ::= Name Eq AttValue
- */
-
-void xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlNodePtr node) {
-    const CHAR *q;
-    CHAR *name, *value = NULL;
-
-    if (!IS_LETTER(ctxt->cur[0]) && (ctxt->cur[0] != '_')) {
-        return;
-    }
-    q = ctxt->cur++;
-    while ((IS_LETTER(ctxt->cur[0])) || (IS_DIGIT(ctxt->cur[0])) ||
-           (ctxt->cur[0] == '.') || (ctxt->cur[0] == '-') ||
-	   (ctxt->cur[0] == '_') || (ctxt->cur[0] == ':') || 
-	   (IS_COMBINING(ctxt->cur[0])) || (IS_IGNORABLE(ctxt->cur[0])) ||
-	   (IS_EXTENDER(ctxt->cur[0])))
-	ctxt->cur++;
-    name = xmlStrndup(q, ctxt->cur - q);
-
-    /*
-     * We should have the equal, we are laxist here and allow attributes
-     * without values and extra spaces.
-     */
-    SKIP_BLANKS(ctxt->cur);
-    if (ctxt->cur[0] == '=') {
-        ctxt->cur++;
-	SKIP_BLANKS(ctxt->cur);
-	if ((ctxt->cur[0] != '\'') && (ctxt->cur[0] != '"')) {
-	    fprintf(stderr, "Quotes were expected for attribute value %.20s\n",
-	            q);
-	} else
-	    value = xmlParseQuotedString(ctxt);
-    }
-
-    /*
-     * Add the attribute to the node.
-     */
-    if (name != NULL) {
-	xmlNewProp(node, name, value);
-        free(name);
-    }
-    if ( value != NULL )
-      free(value);
-}
-
-/*
- * xmlParseStartTag: parse a start of tag.
- */
-
-xmlNodePtr xmlParseStartTag(xmlParserCtxtPtr ctxt) {
-    const CHAR *q;
-    CHAR *ns, *name;
-    xmlDtdPtr dtd = NULL;
-    xmlNodePtr ret = NULL;
-
-    /*
-     * Theorically one should just parse a Name, but with the addition
-     * of the namespace needed for WebDav, it's a bit more complicated
-     * since the element name may be prefixed by a namespace prefix.
-     *
-     * QName ::= (NSPart ':')? LocalPart
-     * NSPart ::= Name
-     * LocalPart ::= Name
-     * STag ::= '<' QName (S Attribute)* S? '>'
-     *
-     * instead of :
-     *
-     * STag ::= '<' QName (S Attribute)* S? '>'
-     */
-    if (ctxt->cur[0] != '<') return(NULL);
-    ctxt->cur++;
-
-    if (!IS_LETTER(ctxt->cur[0]) && (ctxt->cur[0] != '_')) return(NULL);
-    q = ctxt->cur++;
-    while ((IS_LETTER(ctxt->cur[0])) || (IS_DIGIT(ctxt->cur[0])) ||
-           (ctxt->cur[0] == '.') || (ctxt->cur[0] == '-') ||
-	   (ctxt->cur[0] == '_') ||
-	   (IS_COMBINING(ctxt->cur[0])) || (IS_IGNORABLE(ctxt->cur[0])) ||
-	   (IS_EXTENDER(ctxt->cur[0])))
-	ctxt->cur++;
-
-    if (ctxt->cur[0] == ':') {
-        ns = xmlStrndup(q, ctxt->cur - q);
-        
-	ctxt->cur++; /* skip the column */
-	if (!IS_LETTER(ctxt->cur[0]) && (ctxt->cur[0] != '_')) {
-	    fprintf(stderr,
-	       "Start tag : no element name after namespace identifier %.20s\n",
-	            q);
-            free(ns);
-	    return(NULL);
-	}
-	q = ctxt->cur++;
-	while ((IS_LETTER(ctxt->cur[0])) || (IS_DIGIT(ctxt->cur[0])) ||
-	       (ctxt->cur[0] == '.') || (ctxt->cur[0] == '-') ||
-	       (ctxt->cur[0] == '_') || (ctxt->cur[0] == ':') || 
-	       (IS_COMBINING(ctxt->cur[0])) || (IS_IGNORABLE(ctxt->cur[0])) ||
-	       (IS_EXTENDER(ctxt->cur[0])))
-	    ctxt->cur++;
-        name = xmlStrndup(q, ctxt->cur - q);
-
-	/*
-	 * Search the DTD associated to ns.
-	 */
-	dtd = xmlSearchDtd(ctxt->doc, ns);
-	if (dtd == NULL)
-	    fprintf(stderr, "Start tag : Couldn't find namespace %s\n", ns);
-	free(ns);
-    } else
-        name = xmlStrndup(q, ctxt->cur - q);
-
-    ret = xmlNewNode(dtd, name, NULL);
-
-    /*
-     * Now parse the attributes, it ends up with the ending
-     *
-     * (S Attribute)* S?
-     */
-    SKIP_BLANKS(ctxt->cur);
-    while ((IS_CHAR(ctxt->cur[0])) &&
-           (ctxt->cur[0] != '>') && 
-	   ((ctxt->cur[0] != '/') || (ctxt->cur[1] != '>'))) {
-	if (IS_LETTER(ctxt->cur[0]) || (ctxt->cur[0] == '_'))
-	    xmlParseAttribute(ctxt, ret);
-	else {
-	    /* We should warn TODO !!! */
-	    ctxt->cur++;
-	}
-	SKIP_BLANKS(ctxt->cur);
-    }
-
-    return(ret);
-}
-
-/*
- * xmlParseEndTag: parse an end of tag, note that the '</' part has
- * already been read.
- */
-
-void xmlParseEndTag(xmlParserCtxtPtr ctxt, xmlDtdPtr *dtdPtr, CHAR **tagPtr) {
-    const CHAR *q;
-    CHAR *ns, *name;
-    xmlDtdPtr dtd = NULL;
-
-    *dtdPtr = NULL;
-    *tagPtr = NULL;
-
-    /*
-     * Theorically one should just parse a Name, but with the addition
-     * of the namespace needed for WebDav, it's a bit more complicated
-     * since the element name may be prefixed by a namespace prefix.
-     *
-     * QName ::= (NSPart ':')? LocalPart
-     * NSPart ::= Name
-     * LocalPart ::= Name
-     * ETag ::= '</' QName S? '>'
-     *
-     * instead of :
-     *
-     * ETag ::= '</' Name S? '>'
-     */
-    if (!IS_LETTER(ctxt->cur[0]) && (ctxt->cur[0] != '_')) return;
-    q = ctxt->cur++;
-    while ((IS_LETTER(ctxt->cur[0])) || (IS_DIGIT(ctxt->cur[0])) ||
-           (ctxt->cur[0] == '.') || (ctxt->cur[0] == '-') ||
-	   (ctxt->cur[0] == '_') ||
-	   (IS_COMBINING(ctxt->cur[0])) || (IS_IGNORABLE(ctxt->cur[0])) ||
-	   (IS_EXTENDER(ctxt->cur[0])))
-	ctxt->cur++;
-
-    if (ctxt->cur[0] == ':') {
-        ns = xmlStrndup(q, ctxt->cur - q);
-        
-	ctxt->cur++; /* skip the column */
-	if (!IS_LETTER(ctxt->cur[0]) && (ctxt->cur[0] != '_')) {
-	    fprintf(stderr,
-	        "End tag : no element name after namespace identifier %.20s\n",
-	            q);
-            free(ns);
-	    return;
-	}
-	q = ctxt->cur++;
-	while ((IS_LETTER(ctxt->cur[0])) || (IS_DIGIT(ctxt->cur[0])) ||
-	       (ctxt->cur[0] == '.') || (ctxt->cur[0] == '-') ||
-	       (ctxt->cur[0] == '_') || (ctxt->cur[0] == ':') || 
-	       (IS_COMBINING(ctxt->cur[0])) || (IS_IGNORABLE(ctxt->cur[0])) ||
-	       (IS_EXTENDER(ctxt->cur[0])))
-	    ctxt->cur++;
-        name = xmlStrndup(q, ctxt->cur - q);
-
-	/*
-	 * Search the DTD associated to ns.
-	 */
-	dtd = xmlSearchDtd(ctxt->doc, ns);
-	if (dtd == NULL)
-	    fprintf(stderr, "End tag : Couldn't find namespace %s\n", ns);
-	free(ns);
-    } else
-        name = xmlStrndup(q, ctxt->cur - q);
-
-    *dtdPtr = dtd;
-    *tagPtr = name;
-
-    /*
-     * We should definitely be at the ending "S? '>'" part
-     */
-    SKIP_BLANKS(ctxt->cur);
-    if ((!IS_CHAR(ctxt->cur[0])) || (ctxt->cur[0] != '>')) {
-        fprintf(stderr, "End tag : expected '>', got %.20s\n", ctxt->cur);
-	/*
-	 * Note : skipping to the next '>' is probably otherkill,
-	 * especially in case the '>' is hust missing.
-	 *
-	 * Otherwise add:
-	 *  MOVETO_ENDTAG(ctxt->cur);
-	 */
-    } else
-	ctxt->cur++;
-
-    return;
-}
-
-/*
- * xmlParseCDSect: escaped pure raw content.
- */
-CHAR *xmlParseCDSect(xmlParserCtxtPtr ctxt) {
-    const CHAR *r, *s, *base;
-    CHAR *ret;
-
-    base = ctxt->cur;
-    if (!IS_CHAR(ctxt->cur[0])) {
-        fprintf(stderr, "CData section not finished : %.20s\n", base);
-        return(NULL);
-    }
-    r = ctxt->cur++;
-    if (!IS_CHAR(ctxt->cur[0])) {
-        fprintf(stderr, "CData section not finished : %.20s\n", base);
-        return(NULL);
-    }
-    s = ctxt->cur++;
-    while (IS_CHAR(ctxt->cur[0]) &&
-           ((*r != ']') || (*s != ']') || (ctxt->cur[0] != '>'))) {
-        r++;s++;ctxt->cur++;
-    }
-    if (!IS_CHAR(ctxt->cur[0])) {
-        fprintf(stderr, "CData section not finished : %.20s\n", base);
-        return(NULL);
-    }
-    ret = xmlStrndup(base, ctxt->cur-base);
-
-    return(ret);
-}
-
-/*
- * xmlParseContent: a content is
- * (element | PCData | Reference | CDSect | PI | Comment)
- *
- * element : starts by '<'
- * PCData : any CHAR but '&' or '<'
- * Reference : starts by '&'
- * CDSect : starts by '<![CDATA['
- * PI : starts by '<?'
- */
-
-xmlNodePtr xmlParseContent(xmlParserCtxtPtr ctxt, xmlNodePtr node) {
-    const CHAR *q;
-    CHAR *data = NULL;
-    xmlNodePtr ret = NULL;
-
-    /*
-     * First case : a Processing Instruction.
-     */
-    if ((ctxt->cur[0] == '<') && (ctxt->cur[1] == '?')) {
-	xmlParsePI(ctxt);
-    }
-    /*
-     * Second case : a CDSection
-     */
-    if ((ctxt->cur[0] == '<') && (ctxt->cur[1] == '!') &&
-        (ctxt->cur[2] == '[') && (ctxt->cur[3] == 'C') &&
-	(ctxt->cur[4] == 'D') && (ctxt->cur[5] == 'A') &&
-	(ctxt->cur[6] == 'T') && (ctxt->cur[7] == 'A') &&
-	(ctxt->cur[8] == '[')) {
-	ctxt->cur += 9;
-	data = xmlParseCDSect(ctxt);
-    }
-    /*
-     * Third case :  a sub-element.
-     */
-    else if (ctxt->cur[0] == '<') {
-        ret = xmlParseElement(ctxt);
-    }
-    /*
-     * Last case, text. Note that References are handled directly.
-     */
-    else {
-        q = ctxt->cur;
-	while (IS_CHAR(ctxt->cur[0]) && (ctxt->cur[0] != '<')) ctxt->cur++;
-
-	if (!IS_CHAR(ctxt->cur[0])) {
-	    fprintf(stderr, "Truncated content : %.50s\n", q);
-	    return(NULL);
-	}
-
-	/*
-	 * Do the Entities decoding...
-	 */
-	data = xmlStrdup(xmlDecodeEntities(ctxt->doc, q, ctxt->cur - q));
-    }
-
-    /*
-     * Handle the data if any. If there is no child
-     * add it as content, otherwise create a new node of type text.
-     */
-    if (data != NULL)
-	data = xmlHandleData(data);
-    if (data != NULL) {
-	if (node->childs == NULL)
-	    xmlNodeSetContent(node, data); 
-	else 
-	    ret = xmlNewText(data);
-        free(data);
-    }
-
-    return(ret);
-}
-
-/*
- * xmlParseElement: parse an XML element
- */
-
-xmlNodePtr xmlParseElement(xmlParserCtxtPtr ctxt) {
-    xmlNodePtr ret, child;
-    const CHAR *openTag = ctxt->cur;
-    const CHAR *closeTag = ctxt->cur;
-
-    ret = xmlParseStartTag(ctxt);
-    if (ret == NULL) {
-        return(NULL);
-    }
-
-    /*
-     * Check for an Empty Element.
-     */
-    if ((ctxt->cur[0] == '/') && (ctxt->cur[1] == '>')) {
-        ctxt->cur += 2;
-	return(ret);
-    }
-    if (ctxt->cur[0] == '>') ctxt->cur++;
-    else {
-        fprintf(stderr, "Couldn't find end of Start Tag %.30s\n", openTag);
-	return(NULL);
-    }
-
-    /*
-     * Parse the content of the element:
-     * (element | PCData | Reference | CDSect | PI | Comment) *
-     *
-     * element : starts by '<'
-     * PCData : any CHAR but '&' or '<'
-     * Reference : starts by '&'
-     * CDSect : starts by '<![CDATA['
-     * PI : starts by '<?'
-     *
-     * The loop stops upon detection of an end of tag '</'
-     */
-    while ((IS_CHAR(ctxt->cur[0])) &&
-           ((ctxt->cur[0] != '<') || (ctxt->cur[1] != '/'))) {
-        child = xmlParseContent(ctxt, ret);
-	if (child != NULL)
-	    xmlAddChild(ret, child);
-    }
-    if (!IS_CHAR(ctxt->cur[0])) {
-        fprintf(stderr, "Premature end of data in tag %.30s\n", openTag);
-	return(NULL);
-    }
-
-    /*
-     * parse the end of tag : '</' has been detected.
-     */
-    ctxt->cur += 2;
-    if (ctxt->cur[0] == '>') ctxt->cur++; /* simplified closing </> */
-    else {
-        CHAR *endTag;
-	xmlDtdPtr endDtd;
-
-	xmlParseEndTag(ctxt, &endDtd, &endTag);
-
-        /*
-	 * Check that the Name in the ETag is the same as in the STag.
-	 */
-	if (endDtd != ret->dtd) {
-	    fprintf(stderr, "Start and End tags don't use the same DTD:\n");
-	    fprintf(stderr, "\t%.30s\n\t%.30s\n", openTag, closeTag);
-	}
-	if (strcmp(ret->name, endTag)) {
-	    fprintf(stderr, "Start and End tags don't use the same name:\n");
-	    fprintf(stderr, "\t%.30s\n\t%.30s\n", openTag, closeTag);
-	}
-
-        if ( endTag != NULL )
-          free(endTag);
-    }
-
-    return(ret);
-}
-
-/*
- * xmlParseXMLDecl: parse an XML declaration header
- */
-
-void xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
-    CHAR *version;
-
-    /*
-     * We know that '<?xml' is here.
-     */
-    ctxt->cur += 5;
-
-    /*
-     * Parse the version info
-     */
-    SKIP_BLANKS(ctxt->cur);
-
-    /*
-     * We should have 'version=' here !
-     */
-    if ((ctxt->cur[0] == 'v') && (ctxt->cur[1] == 'e') &&
-        (ctxt->cur[2] == 'r') && (ctxt->cur[3] == 's') &&
-	(ctxt->cur[4] == 'i') && (ctxt->cur[5] == 'o') &&
-	(ctxt->cur[6] == 'n') && (ctxt->cur[7] == '=')) {
-	ctxt->cur += 8;
-	version = xmlParseQuotedString(ctxt);
-	if (version == NULL)
-	    ctxt->doc = xmlNewDoc(XML_DEFAULT_VERSION);
-	else {
-	    ctxt->doc = xmlNewDoc(version);
-	    free(version);
-	}
-    } else {
-        ctxt->doc = xmlNewDoc(XML_DEFAULT_VERSION);
-    }
-
-    /*
-     * We should check for Required Markup Declaration TODO !!!!
-     */
-    MOVETO_ENDTAG(ctxt->cur);
-    ctxt->cur++;
-
-}
-
-/*
- * xmlParseMisc: parse an XML Misc optionnal field.
- * (Comment | PI | S)*
- */
-
-void xmlParseMisc(xmlParserCtxtPtr ctxt) {
-    while (((ctxt->cur[0] == '<') && (ctxt->cur[1] == '?')) ||
-           ((ctxt->cur[0] == '<') && (ctxt->cur[1] == '!') &&
-	    (ctxt->cur[2] == '-') && (ctxt->cur[2] == '-')) ||
-           IS_BLANK(ctxt->cur[0])) {
-        if ((ctxt->cur[0] == '<') && (ctxt->cur[1] == '?')) {
-	    xmlParsePI(ctxt);
-	} else if (IS_BLANK(ctxt->cur[0])) {
-	    ctxt->cur++;
-	} else
-	    xmlParserSkipComment(ctxt);
-    }
-}
-
-/*
- * xmlParseDocument : parse an XML document and build a tree.
- */
-
-int xmlParseDocument(xmlParserCtxtPtr ctxt) {
-    /*
-     * We should check for encoding here and plug-in some
-     * conversion code TODO !!!!
-     */
-
-    /*
-     * Wipe out everything which is before the first '<'
-     */
-    SKIP_BLANKS(ctxt->cur);
-
-    /*
-     * Check for the XMLDecl in the Prolog.
-     */
-    if ((ctxt->cur[0] == '<') && (ctxt->cur[1] == '?') &&
-        (ctxt->cur[2] == 'x') && (ctxt->cur[3] == 'm') &&
-	(ctxt->cur[4] == 'l')) {
-	xmlParseXMLDecl(ctxt);
-	/* SKIP_EOL(cur); */
-	SKIP_BLANKS(ctxt->cur);
-    } else if ((ctxt->cur[0] == '<') && (ctxt->cur[1] == '?') &&
-        (ctxt->cur[2] == 'X') && (ctxt->cur[3] == 'M') &&
-	(ctxt->cur[4] == 'L')) {
-	/*
-	 * The first drafts were using <?XML and the final W3C REC
-	 * now use <?xml ...
-	 */
-	xmlParseXMLDecl(ctxt);
-	/* SKIP_EOL(cur); */
-	SKIP_BLANKS(ctxt->cur);
-    } else {
-        ctxt->doc = xmlNewDoc(XML_DEFAULT_VERSION);
-    }
-
-    /*
-     * The Misc part of the Prolog
-     * (Comment | PI | S) *
-     */
-    xmlParseMisc(ctxt);
-
-    /*
-     * Time to start parsing 
-     */
-    ctxt->doc->root = xmlParseElement(ctxt);
-
-    return(0);
-}
-
-/*
- * xmlParseDoc : parse an XML in-memory document and build a tree.
- */
-
-xmlDocPtr xmlParseDoc(CHAR *cur) {
-    xmlDocPtr ret;
-    xmlParserCtxtPtr ctxt;
-
-    if (cur == NULL) return(NULL);
-
-    ctxt = (xmlParserCtxtPtr) malloc(sizeof(xmlParserCtxt));
-    if (ctxt == NULL) {
-        perror("malloc");
-	return(NULL);
-    }
-
-    xmlInitParserCtxt(ctxt);
-    ctxt->base = cur;
-    ctxt->cur = cur;
-
-    xmlParseDocument(ctxt);
-    ret = ctxt->doc;
-    free(ctxt->nodes);
-    free(ctxt);
-    
-    return(ret);
-}
-
-/*
- * xmlParseFile : parse an XML file and build a tree.
- */
-
-xmlDocPtr xmlParseFile(const char *filename) {
-    xmlDocPtr ret;
-#ifdef HAVE_ZLIB_H
-    gzFile input;
-#else
-    int input;
-#endif
-    int res;
-    struct stat buf;
-    char *buffer;
-    xmlParserCtxtPtr ctxt;
-
-    res = stat(filename, &buf);
-    if (res < 0) return(NULL);
-
-#ifdef HAVE_ZLIB_H
-retry_bigger:
-    buffer = malloc((buf.st_size * 20) + 100);
-#else
-    buffer = malloc(buf.st_size + 100);
-#endif
-    if (buffer == NULL) {
-	perror("malloc");
-        return(NULL);
-    }
-
-    memset(buffer, 0, sizeof(buffer));
-#ifdef HAVE_ZLIB_H
-    input = gzopen (filename, "r");
-    if (input == NULL) {
-        fprintf (stderr, "Cannot read file %s :\n", filename);
-	perror ("gzopen failed");
-	return(NULL);
-    }
-#else
-    input = open (filename, O_RDONLY);
-    if (input < 0) {
-        fprintf (stderr, "Cannot read file %s :\n", filename);
-	perror ("open failed");
-	return(NULL);
-    }
-#endif
-#ifdef HAVE_ZLIB_H
-    res = gzread(input, buffer, 20 * buf.st_size);
-#else
-    res = read(input, buffer, buf.st_size);
-#endif
-    if (res < 0) {
-        fprintf (stderr, "Cannot read file %s :\n", filename);
-#ifdef HAVE_ZLIB_H
-	perror ("gzread failed");
-#else
-	perror ("read failed");
-#endif
-	return(NULL);
-    }
-#ifdef HAVE_ZLIB_H
-    gzclose(input);
-    if (res >= 20 * buf.st_size) {
-        free(buffer);
-	buf.st_size *= 2;
-	goto retry_bigger;
-    }
-    buf.st_size = res;
-#else
-    close(input);
-#endif
-
-
-    ctxt = (xmlParserCtxtPtr) malloc(sizeof(xmlParserCtxt));
-    if (ctxt == NULL) {
-        perror("malloc");
-	return(NULL);
-    }
-    buffer[buf.st_size] = '\0';
-
-    xmlInitParserCtxt(ctxt);
-    ctxt->filename = filename;
-    ctxt->base = buffer;
-    ctxt->cur = buffer;
-
-    xmlParseDocument(ctxt);
-    ret = ctxt->doc;
-    free(buffer);
-    free(ctxt->nodes);
-    free(ctxt);
-    
-    return(ret);
-}
-
-/*
- * xmlParseFile : parse an XML memory block and build a tree.
- */
-
-xmlDocPtr xmlParseMemory(char *buffer, int size) {
-    xmlDocPtr ret;
-    xmlParserCtxtPtr ctxt;
-
-    ctxt = (xmlParserCtxtPtr) malloc(sizeof(xmlParserCtxt));
-    if (ctxt == NULL) {
-        perror("malloc");
-	return(NULL);
-    }
-
-    buffer[size - 1] = '\0';
-
-    xmlInitParserCtxt(ctxt);
-    ctxt->base = buffer;
-    ctxt->cur = buffer;
-
-    xmlParseDocument(ctxt);
-    ret = ctxt->doc;
-    free(ctxt->nodes);
-    free(ctxt);
-    
-    return(ret);
-}
-
-
-
-
-/* Initialize parser context */
-void xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
-{
-    int i;
-
-    ctxt->filename = NULL;
-    ctxt->base = NULL;
-    ctxt->cur = NULL;
-    ctxt->line = 1;
-    ctxt->col = 1;
-    ctxt->doc = NULL;
-    ctxt->depth = 0;
-    ctxt->max_depth = 10;
-    ctxt->nodes = (xmlNodePtr *) malloc(ctxt->max_depth * sizeof(xmlNodePtr));
-    if (ctxt->nodes == NULL) {
-	fprintf(stderr, "malloc of %d byte failed\n",
-		ctxt->max_depth * sizeof(xmlNodePtr));
-	ctxt->max_depth = 0;
-    } else {
-        for (i = 0;i < ctxt->max_depth;i++) 
-	    ctxt->nodes[i] = NULL;
-    }
-}
-
-
-/*
- * Clear (release owned resources) and reinitialize context
- */
-void xmlClearParserCtxt(xmlParserCtxtPtr ctx)
-{
-    xmlInitParserCtxt(ctx);
-}
-
-
-/*
- * Setup the parser context to parse a new buffer; Clears any prior
- * contents from the parser context. The buffer parameter must not be
- * NULL, but the filename parameter can be
- */
-void xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const CHAR* buffer,
-                             const char* filename)
-{
-  xmlClearParserCtxt(ctxt);
-  ctxt->base = buffer;
-  ctxt->cur = buffer;
-  ctxt->filename = filename;
-}
-
-
-
-void xmlReportError(xmlParserCtxtPtr ctx, const CHAR* msg)
-{
-  fputs(msg, stderr);
-}
diff --git a/xml_parser.h b/xml_parser.h
deleted file mode 100644
index a20c95a..0000000
--- a/xml_parser.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * parser.h : constants and stuff related to the XML parser.
- *
- * See Copyright for the status of this software.
- *
- * $Id$
- */
-
-#ifndef __XML_PARSER_H__
-#define __XML_PARSER_H__
-
-#include "xml_tree.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Constants.
- */
-#define XML_DEFAULT_VERSION	"1.0"
-
-
-typedef struct xmlParserCtxt {
-    const char *filename;             /* The file analyzed, if any */
-    const CHAR *base;                 /* Base of the array to parse */
-    const CHAR *cur;                  /* Current char being parsed */
-    int line;                         /* Current line */
-    int col;                          /* Current column */
-    xmlDocPtr doc;                    /* the document being built */
-    int depth;                        /* Depth of current element */
-    int max_depth;                    /* Max depth allocated */
-    xmlNodePtr *nodes;                /* The node hierarchy being built */
-} xmlParserCtxt, *xmlParserCtxtPtr;
-
-/*
- * Interfaces
- */
-extern int xmlParseDocument(xmlParserCtxtPtr ctxt);
-extern xmlDocPtr xmlParseDoc(CHAR *cur);
-extern xmlDocPtr xmlParseMemory(char *buffer, int size);
-extern xmlDocPtr xmlParseFile(const char *filename);
-extern CHAR *xmlStrdup(const CHAR *input);
-extern CHAR *xmlStrndup(const CHAR *input, int n);
-extern CHAR *xmlStrchr(const CHAR *str, CHAR val);
-extern int xmlStrcmp(const CHAR *str1, const CHAR *str2);
-extern int xmlStrncmp(const CHAR *str1, const CHAR *str2, int len);
-
-extern void xmlInitParserCtxt(xmlParserCtxtPtr ctx);
-extern void xmlClearParserCtxt(xmlParserCtxtPtr ctx);
-extern void xmlSetupParserForBuffer(xmlParserCtxtPtr ctx, const CHAR* buffer,
-                                    const char* filename);
-
-extern void xmlReportError(xmlParserCtxtPtr ctx, const CHAR* msg);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __XML_PARSER_H__ */
-
diff --git a/xml_tree.c b/xml_tree.c
deleted file mode 100644
index e939a47..0000000
--- a/xml_tree.c
+++ /dev/null
@@ -1,731 +0,0 @@
-/*
- * tree.c : implemetation of access function for an XML tree.
- *
- * See Copyright for the status of this software.
- *
- * $Id$
- */
-
-#include <stdio.h>
-#include <ctype.h>
-#include <malloc.h>
-#include <string.h> /* for memset() only ! */
-
-#include "xml_tree.h"
-#include "xml_entities.h"
-
-static CHAR xmlStringText[] = { 't', 'e', 'x', 't', 0 };
-int oldXMLWDcompatibility = 0;
-
-/************************************************************************
- *									*
- *		Allocation and deallocation of basic structures		*
- *									*
- ************************************************************************/
- 
-/*
- * Creation of a new DTD.
- */
-xmlDtdPtr xmlNewDtd(xmlDocPtr doc, const CHAR *href, const CHAR *AS) {
-    xmlDtdPtr cur;
-
-    /*
-     * Allocate a new DTD and fill the fields.
-     */
-    cur = (xmlDtdPtr) malloc(sizeof(xmlDtd));
-    if (cur == NULL) {
-        fprintf(stderr, "xmlNewDtd : malloc failed\n");
-	return(NULL);
-    }
-
-    cur->next = NULL;
-    if (href != NULL)
-	cur->href = xmlStrdup(href); 
-    else
-        cur->href = NULL;
-    if (AS != NULL)
-	cur->AS = xmlStrdup(AS); 
-    else
-        cur->AS = NULL;
-    if (doc != NULL) {
-	cur->next = doc->dtds;
-        doc->dtds = cur;
-    }
-
-    return(cur);
-}
-
-/*
- * Freeing a DTD
- */
-void xmlFreeDtd(xmlDtdPtr cur) {
-    if (cur == NULL) {
-        fprintf(stderr, "xmlFreeDtd : DTD == NULL\n");
-	return;
-    }
-    if (cur->href != NULL) free((char *) cur->href);
-    if (cur->AS != NULL) free((char *) cur->AS);
-    memset(cur, -1, sizeof(xmlDtd));
-    free(cur);
-}
-
-/*
- * Freeing a DTD list
- */
-void xmlFreeDtdList(xmlDtdPtr cur) {
-    xmlDtdPtr next;
-    if (cur == NULL) {
-        fprintf(stderr, "xmlFreeDtdList : dtd == NULL\n");
-	return;
-    }
-    while (cur != NULL) {
-        next = cur->next;
-        xmlFreeDtd(cur);
-	cur = next;
-    }
-}
-
-/*
- * Creation of a new document
- */
-xmlDocPtr xmlNewDoc(const CHAR *version) {
-    xmlDocPtr cur;
-
-    if (version == NULL) {
-        fprintf(stderr, "xmlNewDoc : version == NULL\n");
-	return(NULL);
-    }
-
-    /*
-     * Allocate a new document and fill the fields.
-     */
-    cur = (xmlDocPtr) malloc(sizeof(xmlDoc));
-    if (cur == NULL) {
-        fprintf(stderr, "xmlNewDoc : malloc failed\n");
-	return(NULL);
-    }
-
-    cur->version = xmlStrdup(version); 
-    cur->root = NULL; 
-    cur->dtds = NULL;
-    return(cur);
-}
-
-/*
- * Freeing a document : all the tree is freed too.
- */
-void xmlFreeDoc(xmlDocPtr cur) {
-    if (cur == NULL) {
-        fprintf(stderr, "xmlFreeDoc : document == NULL\n");
-	return;
-    }
-    free((char *) cur->version);
-    if (cur->root != NULL) xmlFreeNode(cur->root);
-    if (cur->dtds != NULL) xmlFreeDtdList(cur->dtds);
-    memset(cur, -1, sizeof(xmlDoc));
-    free(cur);
-}
-
-/*
- * Creation of a new property element in a given DTD.
- */
-xmlPropPtr xmlNewProp(xmlNodePtr node, const CHAR *name, const CHAR *value) {
-    xmlPropPtr cur;
-
-    if (name == NULL) {
-        fprintf(stderr, "xmlNewProp : name == NULL\n");
-	return(NULL);
-    }
-
-    /*
-     * Allocate a new property and fill the fields.
-     */
-    cur = (xmlPropPtr) malloc(sizeof(xmlProp));
-    if (cur == NULL) {
-        fprintf(stderr, "xmlNewProp : malloc failed\n");
-	return(NULL);
-    }
-
-    cur->node = node; 
-    cur->name = xmlStrdup(name);
-    if (value != NULL)
-	cur->value = xmlStrdup(value);
-    else 
-	cur->value = NULL;
-    if (node != NULL) {
-	cur->next = node->properties;
-        node->properties = cur;
-    } else
-	cur->next = NULL; 
-    return(cur);
-}
-
-/*
- * Freeing a property list : Free a property and all its siblings,
- *                       this is a recursive behaviour, all the childs
- *                       are freed too.
- */
-void xmlFreePropList(xmlPropPtr cur) {
-    xmlPropPtr next;
-    if (cur == NULL) {
-        fprintf(stderr, "xmlFreePropList : property == NULL\n");
-	return;
-    }
-    while (cur != NULL) {
-        next = cur->next;
-        xmlFreeProp(cur);
-	cur = next;
-    }
-}
-
-/*
- * Freeing a property.
- */
-void xmlFreeProp(xmlPropPtr cur) {
-    if (cur == NULL) {
-        fprintf(stderr, "xmlFreeProp : property == NULL\n");
-	return;
-    }
-    if (cur->name != NULL) free((char *) cur->name);
-    if (cur->value != NULL) free((char *) cur->value);
-    memset(cur, -1, sizeof(xmlProp));
-    free(cur);
-}
-
-/*
- * Creation of a new node element in a given DTD.
- * We don't assume that the "name" has already being strdup'd anymore !
- */
-xmlNodePtr xmlNewNode(xmlDtdPtr dtd, const CHAR *name, CHAR *content) {
-    xmlNodePtr cur;
-
-    if (name == NULL) {
-        fprintf(stderr, "xmlNewNode : name == NULL\n");
-	return(NULL);
-    }
-
-    /*
-     * Allocate a new node and fill the fields.
-     */
-    cur = (xmlNodePtr) malloc(sizeof(xmlNode));
-    if (cur == NULL) {
-        fprintf(stderr, "xmlNewNode : malloc failed\n");
-	return(NULL);
-    }
-
-    cur->parent = NULL; 
-    cur->next = NULL; 
-    cur->childs = NULL; 
-    cur->properties = NULL; 
-    cur->type = 0;
-    cur->name = xmlStrdup(name);
-    cur->dtd = dtd;
-    if (content != NULL)
-	cur->content = xmlStrdup(content);
-    else 
-	cur->content = NULL;
-    return(cur);
-}
-
-/*
- * Creation of a new node contening text.
- */
-xmlNodePtr xmlNewText(CHAR *content) {
-    xmlNodePtr cur;
-
-    /*
-     * Allocate a new node and fill the fields.
-     */
-    cur = (xmlNodePtr) malloc(sizeof(xmlNode));
-    if (cur == NULL) {
-        fprintf(stderr, "xmlNewNode : malloc failed\n");
-	return(NULL);
-    }
-
-    cur->parent = NULL; 
-    cur->next = NULL; 
-    cur->childs = NULL; 
-    cur->properties = NULL; 
-    cur->type = XML_TYPE_TEXT;
-    cur->name = xmlStrdup(xmlStringText);;
-    cur->dtd = NULL;
-    if (content != NULL)
-	cur->content = xmlStrdup(content);
-    else 
-	cur->content = NULL;
-    return(cur);
-}
-
-/*
- * Creation of a new child element, added at the end.
- */
-xmlNodePtr xmlNewChild(xmlNodePtr parent, xmlDtdPtr dtd,
-                       const CHAR *name, CHAR *content) {
-    xmlNodePtr cur, prev;
-
-    if (parent == NULL) {
-        fprintf(stderr, "xmlNewChild : parent == NULL\n");
-	return(NULL);
-    }
-
-    if (name == NULL) {
-        fprintf(stderr, "xmlNewChild : name == NULL\n");
-	return(NULL);
-    }
-
-    /*
-     * Allocate a new node
-     */
-    if (dtd == NULL)
-	cur = xmlNewNode(parent->dtd, name, content);
-    else
-	cur = xmlNewNode(dtd, name, content);
-    if (cur == NULL) return(NULL);
-
-    /*
-     * add the new element at the end of the childs list.
-     */
-    cur->parent = parent;
-    if (parent->childs == NULL) {
-        parent->childs = cur;
-    } else {
-        prev = parent->childs;
-	while (prev->next != NULL) prev = prev->next;
-	prev->next = cur;
-    }
-
-    return(cur);
-}
-
-/*
- * Add a new child element, added at the end.
- */
-xmlNodePtr xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
-    xmlNodePtr prev;
-
-    if (parent == NULL) {
-        fprintf(stderr, "xmladdChild : parent == NULL\n");
-	return(NULL);
-    }
-
-    if (cur == NULL) {
-        fprintf(stderr, "xmladdChild : child == NULL\n");
-	return(NULL);
-    }
-
-    /*
-     * add the new element at the end of the childs list.
-     */
-    cur->parent = parent;
-    if (parent->childs == NULL) {
-        parent->childs = cur;
-    } else {
-        prev = parent->childs;
-	while (prev->next != NULL) prev = prev->next;
-	prev->next = cur;
-    }
-
-    return(cur);
-}
-
-/*
- * Freeing a node list : Free a node and all its siblings,
- *                       this is a recursive behaviour, all the childs
- *                       are freed too.
- */
-void xmlFreeNodeList(xmlNodePtr cur) {
-    xmlNodePtr next;
-    if (cur == NULL) {
-        fprintf(stderr, "xmlFreeNodeList : node == NULL\n");
-	return;
-    }
-    while (cur != NULL) {
-        next = cur->next;
-        xmlFreeNode(cur);
-	cur = next;
-    }
-}
-
-/*
- * Freeing a node : this is a recursive behaviour, all the childs
- *                  are freed too.
- */
-void xmlFreeNode(xmlNodePtr cur) {
-    if (cur == NULL) {
-        fprintf(stderr, "xmlFreeNode : node == NULL\n");
-	return;
-    }
-    if (cur->properties != NULL) xmlFreePropList(cur->properties);
-    if (cur->childs != NULL) xmlFreeNodeList(cur->childs);
-    if (cur->content != NULL) free(cur->content);
-    if (cur->name != NULL) free((char *) cur->name);
-    memset(cur, -1, sizeof(xmlNode));
-    free(cur);
-}
-
-/************************************************************************
- *									*
- *		Content access functions				*
- *									*
- ************************************************************************/
- 
-/*
- * Changing the content of a node.
- */
-void xmlNodeSetContent(xmlNodePtr cur, CHAR *content) {
-    if (cur == NULL) {
-        fprintf(stderr, "xmlNodeSetContent : node == NULL\n");
-	return;
-    }
-    if (cur->content != NULL) free(cur->content);
-    if (content != NULL)
-	cur->content = xmlStrdup(content);
-    else 
-	cur->content = NULL;
-}
-
-/*
- * Search a Dtd registered under a given name space for a document.
- */
-xmlDtdPtr xmlSearchDtd(xmlDocPtr doc, CHAR *nameSpace) {
-    xmlDtdPtr cur;
-
-    if ((doc == NULL) || (nameSpace == NULL)) return(NULL);
-
-    cur = doc->dtds;
-    while (cur != NULL) {
-        if ((cur->AS != NULL) && (!xmlStrcmp(cur->AS, nameSpace)))
-	    return(cur);
-	cur = cur->next;
-    }
-    return(NULL);
-}
-
-/*
- * Reading the content of a given property.
- */
-const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name) {
-    xmlPropPtr prop = node->properties;
-
-    while (prop != NULL) {
-        if (!xmlStrcmp(prop->name, name)) return(prop->value);
-	prop = prop->next;
-    }
-    return(NULL);
-}
-
-/************************************************************************
- *									*
- *			Output : to a FILE or in memory			*
- *									*
- ************************************************************************/
-
-/*
- * routine which manage and grows an output buffer. One can write
- * standard char array's (8 bits char) or CHAR's arrays.
- */
-static CHAR *buffer = NULL;
-static int buffer_index = 0;
-static int buffer_size = 0;
-
-static void xmlBufferWriteCHAR(const CHAR *string) {
-    const CHAR *cur;
-
-    if (buffer == NULL) {
-        buffer_size = 50000;
-        buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
-	if (buffer == NULL) {
-	    fprintf(stderr, "xmlBufferWrite : out of memory!\n");
-	    exit(1);
-	}
-    }
-    
-    if (string == NULL) return;
-    for (cur = string;*cur != 0;cur++) {
-        if (buffer_index  + 10 >= buffer_size) {
-	    buffer_size *= 2;
-	    buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
-	    if (buffer == NULL) {
-	        fprintf(stderr, "xmlBufferWrite : out of memory!\n");
-		exit(1);
-	    }
-	}
-        buffer[buffer_index++] = *cur;
-    }
-    buffer[buffer_index] = 0;
-}
-
-static void xmlBufferWriteChar(const char *string) {
-    const CHAR *cur;
-
-    if (buffer == NULL) {
-        buffer_size = 50000;
-        buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
-	if (buffer == NULL) {
-	    fprintf(stderr, "xmlBufferWrite : out of memory!\n");
-	    exit(1);
-	}
-    }
-    
-    if (string == NULL) return;
-    for (cur = string;*cur != 0;cur++) {
-        if (buffer_index  + 10 >= buffer_size) {
-	    buffer_size *= 2;
-	    buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
-	    if (buffer == NULL) {
-	        fprintf(stderr, "xmlBufferWrite : out of memory!\n");
-		exit(1);
-	    }
-	}
-        buffer[buffer_index++] = *cur;
-    }
-    buffer[buffer_index] = 0;
-}
-
-/*
- * Dump a DTD to the given FD
- */
-static void xmlDtdDump(xmlDtdPtr cur) {
-    if (cur == NULL) {
-        fprintf(stderr, "xmlDtdDump : DTD == NULL\n");
-	return;
-    }
-    if (oldXMLWDcompatibility) {
-	xmlBufferWriteChar("<?namespace");
-	if (cur->href != NULL) {
-	    xmlBufferWriteChar(" href=\"");
-	    xmlBufferWriteCHAR(cur->href);
-	    xmlBufferWriteChar("\"");
-	}
-	if (cur->AS != NULL) {
-	    xmlBufferWriteChar(" AS=\"");
-	    xmlBufferWriteCHAR(cur->AS);
-	    xmlBufferWriteChar("\"");
-	}
-	xmlBufferWriteChar("?>\n");
-    } else {
-	xmlBufferWriteChar("<?xml:namespace");
-	if (cur->href != NULL) {
-	    xmlBufferWriteChar(" ns=\"");
-	    xmlBufferWriteCHAR(cur->href);
-	    xmlBufferWriteChar("\"");
-	}
-	if (cur->AS != NULL) {
-	    xmlBufferWriteChar(" prefix=\"");
-	    xmlBufferWriteCHAR(cur->AS);
-	    xmlBufferWriteChar("\"");
-	}
-	xmlBufferWriteChar("?>\n");
-    }
-}
-
-/*
- * Dump an XML property to the given FD
- */
-
-static void xmlPropDump(xmlDocPtr doc, xmlPropPtr cur) {
-    if (cur == NULL) {
-        fprintf(stderr, "xmlPropDump : property == NULL\n");
-	return;
-    }
-    xmlBufferWriteChar(" ");
-    xmlBufferWriteCHAR(cur->name);
-    if (cur->value) {
-	xmlBufferWriteChar("=\"");
-	xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->value));
-	xmlBufferWriteChar("\"");
-    }
-}
-
-/*
- * Dump an XML property list to the given FD
- */
-
-static void xmlPropListDump(xmlDocPtr doc, xmlPropPtr cur) {
-    if (cur == NULL) {
-        fprintf(stderr, "xmlPropListDump : property == NULL\n");
-	return;
-    }
-    while (cur != NULL) {
-        xmlPropDump(doc, cur);
-	cur = cur->next;
-    }
-}
-
-/*
- * Dump an XML node list to the given FD
- */
-
-static void xmlNodeDump(xmlDocPtr doc, xmlNodePtr cur, int level);
-static void xmlNodeListDump(xmlDocPtr doc, xmlNodePtr cur, int level) {
-    if (cur == NULL) {
-        fprintf(stderr, "xmlNodeListDump : node == NULL\n");
-	return;
-    }
-    while (cur != NULL) {
-        xmlNodeDump(doc, cur, level);
-	cur = cur->next;
-    }
-}
-
-/*
- * Dump an XML node to the given FD
- */
-
-static void xmlNodeDump(xmlDocPtr doc, xmlNodePtr cur, int level) {
-    int i;
-
-    if (cur == NULL) {
-        fprintf(stderr, "xmlNodeDump : node == NULL\n");
-	return;
-    }
-    if (cur->type == XML_TYPE_TEXT) {
-	if (cur->content != NULL)
-	    xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->content));
-	return;
-    }
-    for (i = 0;i < level;i++)
-        xmlBufferWriteChar("  ");
-
-    xmlBufferWriteChar("<");
-    if ((cur->dtd != NULL) && (cur->dtd->AS != NULL)) {
-        xmlBufferWriteCHAR(cur->dtd->AS);
-	xmlBufferWriteChar(":");
-    }
-
-    xmlBufferWriteCHAR(cur->name);
-    if (cur->properties != NULL)
-        xmlPropListDump(doc, cur->properties);
-
-    if ((cur->content == NULL) && (cur->childs == NULL)) {
-        xmlBufferWriteChar("/>\n");
-	return;
-    }
-    xmlBufferWriteChar(">");
-    if (cur->content != NULL)
-	xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->content));
-    if (cur->childs != NULL) {
-	xmlBufferWriteChar("\n");
-	xmlNodeListDump(doc, cur->childs, level + 1);
-	for (i = 0;i < level;i++)
-	    xmlBufferWriteChar("  ");
-    }
-    xmlBufferWriteChar("</");
-    if ((cur->dtd != NULL) && (cur->dtd->AS != NULL)) {
-        xmlBufferWriteCHAR(cur->dtd->AS);
-	xmlBufferWriteChar(":");
-    }
-
-    xmlBufferWriteCHAR(cur->name);
-    xmlBufferWriteChar(">\n");
-}
-
-/*
- * Dump an XML DTD list to the given FD
- */
-
-static void xmlDtdListDump(xmlDtdPtr cur) {
-    if (cur == NULL) {
-        fprintf(stderr, "xmlDtdListDump : DTD == NULL\n");
-	return;
-    }
-    while (cur != NULL) {
-        xmlDtdDump(cur);
-	cur = cur->next;
-    }
-}
-
-/*
- * Dump an XML document to memory.
- */
-
-void xmlDocDumpMemory(xmlDocPtr cur, CHAR**mem, int *size) {
-    if (cur == NULL) {
-        fprintf(stderr, "xmlDocDump : document == NULL\n");
-	*mem = NULL;
-	*size = 0;
-	return;
-    }
-    buffer_index = 0;
-    if (oldXMLWDcompatibility)
-	xmlBufferWriteChar("<?XML version=\"");
-    else 
-	xmlBufferWriteChar("<?xml version=\"");
-    xmlBufferWriteCHAR(cur->version);
-    xmlBufferWriteChar("\"?>\n");
-    if (cur->dtds != NULL)
-        xmlDtdListDump(cur->dtds);
-    if (cur->root != NULL)
-        xmlNodeDump(cur, cur->root, 0);
-
-    *mem = buffer;
-    *size = buffer_index;
-}
-
-/*
- * Dump an XML document to the given FD
- */
-
-void xmlDocDump(FILE *f, xmlDocPtr cur) {
-    if (cur == NULL) {
-        fprintf(stderr, "xmlDocDump : document == NULL\n");
-	return;
-    }
-    buffer_index = 0;
-    if (oldXMLWDcompatibility)
-	xmlBufferWriteChar("<?XML version=\"");
-    else 
-	xmlBufferWriteChar("<?xml version=\"");
-    xmlBufferWriteCHAR(cur->version);
-    xmlBufferWriteChar("\"?>\n");
-    if (cur->dtds != NULL)
-        xmlDtdListDump(cur->dtds);
-    if (cur->root != NULL)
-        xmlNodeDump(cur, cur->root, 0);
-
-    fwrite(buffer, sizeof(CHAR), buffer_index, f);
-}
-
-/************************************************************************
- *									*
- *				Debug					*
- *									*
- ************************************************************************/
-
-#ifdef DEBUG_TREE
-int main(void) {
-    xmlDocPtr doc;
-    xmlNodePtr tree, subtree;
-    xmlDtdPtr dtd1;
-    xmlDtdPtr dtd2;
-
-    /*
-     * build a fake XML document
-     */
-    doc = xmlNewDoc("1.0");
-    dtd1 = xmlNewDtd(doc, "http://www.ietf.org/standards/dav/", "D");
-    dtd2 = xmlNewDtd(doc, "http://www.w3.com/standards/z39.50/", "Z");
-    doc->root = xmlNewNode(dtd1, "multistatus", NULL);
-    tree = xmlNewChild(doc->root, NULL, "response", NULL);
-    subtree = xmlNewChild(tree, NULL, "prop", NULL);
-    xmlNewChild(subtree, dtd2, "Authors", NULL);
-    subtree = xmlNewChild(tree, NULL, "status", "HTTP/1.1 420 Method Failure");
-    tree = xmlNewChild(doc->root, NULL, "response", NULL);
-    subtree = xmlNewChild(tree, NULL, "prop", NULL);
-    xmlNewChild(subtree, dtd2, "Copyright-Owner", NULL);
-    subtree = xmlNewChild(tree, NULL, "status", "HTTP/1.1 409 Conflict");
-    tree = xmlNewChild(doc->root, NULL, "responsedescription",
-                       "Copyright Owner can not be deleted or altered");
-
-    /*
-     * print it.
-     */
-    xmlDocDump(stdout, doc);
-
-    /*
-     * free it.
-     */
-    xmlFreeDoc(doc);
-    return(0);
-}
-#endif
diff --git a/xml_tree.h b/xml_tree.h
deleted file mode 100644
index 00322c1..0000000
--- a/xml_tree.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * tree.h : describes the structures found in an tree resulting
- *          from an XML parsing.
- *
- * See Copyright for the status of this software.
- *
- * $Id$
- */
-
-#ifndef __XML_TREE_H__
-#define __XML_TREE_H__
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Type definitions
- */
-#ifdef UNICODE
-typedef unsigned short CHAR;
-#else
-typedef unsigned char CHAR;
-#endif
-
-/*
- * Constants.
- */
-#define XML_TYPE_TEXT		1
-
-/*
- * An XML DTD defining a given name space.
- */
-typedef struct xmlDtd {
-    struct xmlDtd *next;	/* next Dtd link for this document  */
-    const CHAR    *href;	/* URL for the DTD */
-    const CHAR    *AS;	        /* URL for the DTD */
-    void          *entities;    /* Hash table for entities if any */
-} xmlDtd, *xmlDtdPtr;
-
-/*
- * A property of an XML node.
- */
-typedef struct xmlProp {
-    struct xmlNode *node;	/* prop->node link */
-    struct xmlProp *next;	/* parent->childs link */
-    const CHAR     *name;       /* the name of the property */
-    const CHAR     *value;      /* the value of the property */
-} xmlProp, *xmlPropPtr;
-
-/*
- * A node in an XML tree.
- */
-typedef struct xmlNode {
-    struct xmlNode *parent;	/* child->parent link */
-    struct xmlNode *next;	/* next sibling link  */
-    struct xmlNode *childs;	/* parent->childs link */
-    struct xmlProp *properties;	/* properties list */
-    int             type;	/* type number in the DTD */
-    const CHAR     *name;       /* the name of the node */
-    xmlDtd         *dtd;        /* pointer to the DTD */
-    CHAR           *content;    /* the content */
-} xmlNode, *xmlNodePtr;
-
-/*
- * An XML document.
- */
-typedef struct xmlDoc {
-    const CHAR     *version;	/* the XML version string */
-    struct xmlDtd  *dtds;       /* referenced DTDs */
-    struct xmlNode *root;	/* parent->childs link */
-    void           *entities;   /* Hash table for entities if any */
-} xmlDoc, *xmlDocPtr;
-
-/*
- * Variables.
- */
-extern xmlDtdPtr baseDTD;
-extern int oldXMLWDcompatibility;/* maintain compatibility with old WD */
-
-/*
- * Functions.
- */
-extern xmlDtdPtr xmlNewDtd(xmlDocPtr doc, const CHAR *href, const CHAR *AS);
-extern void xmlFreeDtd(xmlDtdPtr cur);
-extern xmlDocPtr xmlNewDoc(const CHAR *version);
-extern void xmlFreeDoc(xmlDocPtr cur);
-extern xmlPropPtr xmlNewProp(xmlNodePtr node, const CHAR *name,
-                             const CHAR *value);
-extern const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name);
-extern void xmlFreePropList(xmlPropPtr cur);
-extern void xmlFreeProp(xmlPropPtr cur);
-extern xmlNodePtr xmlNewNode(xmlDtdPtr dtd, const CHAR *name, CHAR *content);
-extern xmlNodePtr xmlNewText(CHAR *content);
-extern xmlNodePtr xmlAddChild(xmlNodePtr parent, xmlNodePtr cur);
-extern void xmlFreeNodeList(xmlNodePtr cur);
-extern void xmlFreeNode(xmlNodePtr cur);
-extern void xmlNodeSetContent(xmlNodePtr cur, CHAR *content);
-extern xmlDtdPtr xmlSearchDtd(xmlDocPtr doc, CHAR *nameSpace);
-extern xmlNodePtr xmlNewChild(xmlNodePtr parent, xmlDtdPtr dtd,
-                              const CHAR *name, CHAR *content);
-
-extern void xmlDocDumpMemory(xmlDocPtr cur, CHAR**mem, int *size);
-extern void xmlDocDump(FILE *f, xmlDocPtr doc);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __XML_TREE_H__ */
-