- Large resync between W3C and Gnome tree
- configure.in: 2.1.0 prerelease
- example/Makefile.am example/gjobread.c tree.h: work on
  libxml1 libxml2 convergence.
- nanoftp, nanohttp.c: fixed stalled connections probs
- HTMLtree.c SAX.c : support for attribute without values in
  HTML for andersca
- valid.c: Fixed most validation + namespace problems
- HTMLparser.c: start document callback for andersca
- debugXML.c xpath.c: lots of XPath fixups from Picdar Technology
- parser.h, SAX.c: serious speed improvement for large
  CDATA blocks
- encoding.[ch] xmlIO.[ch]: Improved seriously saving to
  different encoding
- config.h.in parser.c xmllint.c: added xmlCheckVersion()
  and the LIBXML_TEST_VERSION macro
Daniel
diff --git a/ChangeLog b/ChangeLog
index cc6b43c..37094c4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+Wed Jun 28 23:10:26 MEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in: 2.1.0 prerelease
+	* Large resync between W3C and Gnome tree
+	* nanoftp, nanohttp.c: fixed stalled connections probs
+	* HTMLtree.c SAX.c : support for attribute without values in
+	  HTML for andersca
+	* valid.c: Fixed most validation + namespace problems
+	* HTMLparser.c: start document callback for andersca
+	* debugXML.c xpath.c: lots of XPath fixups from Picdar Technology
+	* parser.h, SAX.c: serious speed improvement for large
+	  CDATA blocks
+	* encoding.[ch] xmlIO.[ch]: Improved seriously saving to
+	  different encoding
+	* example/Makefile.am example/gjobread.c tree.h: work on 
+	  libxml1 libxml2 convergence.
+	* config.h.in parser.c xmllint.c: added xmlCheckVersion()
+	  and the LIBXML_TEST_VERSION macro
+
 Fri Jun 23 22:26:07 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
 
 	* doc/xml.html: various patches and improvements typo fixed by
diff --git a/HTMLparser.c b/HTMLparser.c
index 5c1cfae..cfd65bd 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -388,6 +388,7 @@
 NULL
 };
 
+
 static char** htmlStartCloseIndex[100];
 static int htmlStartCloseIndexinitialized = 0;
 
@@ -604,6 +605,54 @@
     }
 }
 
+/**
+ * htmlCheckImplied:
+ * @ctxt:  an HTML parser context
+ * @new:  The new tag name
+ *
+ * The HTmL DtD allows a tag to exists only implicitely
+ * called when a new tag has been detected and generates the
+ * appropriates implicit tags if missing
+ */
+void
+htmlCheckImplied(htmlParserCtxtPtr ctxt, const xmlChar *new) {
+    if (!strcmp(new, "html"))
+	return;
+    if (ctxt->nameNr <= 0) {
+#ifdef DEBUG
+	fprintf(stderr,"Implied element html: pushed html\n");
+#endif    
+	htmlnamePush(ctxt, xmlStrdup(BAD_CAST"html"));
+	if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
+	    ctxt->sax->startElement(ctxt->userData, BAD_CAST"html", NULL);
+    }
+    if ((!strcmp(new, "body")) || (!strcmp(new, "head")))
+        return;
+    if (ctxt->nameNr <= 1) {
+	if ((!strcmp(new, "script")) || (!strcmp(new, "style")) ||
+	    (!strcmp(new, "meta")) || (!strcmp(new, "link")) ||
+	    (!strcmp(new, "title")) || (!strcmp(new, "base"))) {
+	    /* 
+	     * dropped OBJECT ... i you put it first BODY will be
+	     * assumed !
+	     */
+#ifdef DEBUG
+	    fprintf(stderr,"Implied element head: pushed head\n");
+#endif    
+	    htmlnamePush(ctxt, xmlStrdup(BAD_CAST"head"));
+	    if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
+		ctxt->sax->startElement(ctxt->userData, BAD_CAST"head", NULL);
+	} else {
+#ifdef DEBUG
+	    fprintf(stderr,"Implied element body: pushed body\n");
+#endif    
+	    htmlnamePush(ctxt, xmlStrdup(BAD_CAST"body"));
+	    if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
+		ctxt->sax->startElement(ctxt->userData, BAD_CAST"body", NULL);
+	}
+    }
+}
+
 /************************************************************************
  *									*
  * 		The list of HTML predefined entities			*
@@ -1322,6 +1371,7 @@
 		    BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd");
     else
 	xmlCreateIntSubset(cur, BAD_CAST "HTML", ExternalID, URI);
+    cur->doc = cur;
     cur->name = NULL;
     cur->children = NULL; 
     cur->extSubset = NULL;
@@ -2161,11 +2211,12 @@
         NEXT;
 	SKIP_BLANKS;
 	val = htmlParseAttValue(ctxt);
+	/******
     } else {
-        /* TODO : some attribute must have values, some may not */
+        * TODO : some attribute must have values, some may not
 	if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
 	    ctxt->sax->warning(ctxt->userData,
-	       "No value for attribute %s\n", name);
+	       "No value for attribute %s\n", name); */
     }
 
     *value = val;
@@ -2220,6 +2271,11 @@
     htmlAutoClose(ctxt, name);
 
     /*
+     * Check for implied HTML elements.
+     */
+    htmlCheckImplied(ctxt, name);
+
+    /*
      * Now parse the attributes, it ends up with the ending
      *
      * (S Attribute)* S?
@@ -2759,6 +2815,10 @@
 	ctxt->wellFormed = 0;
     }
 
+    if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
+	ctxt->sax->startDocument(ctxt->userData);
+
+
     /*
      * Parse possible comments before any content
      */
diff --git a/HTMLtree.c b/HTMLtree.c
index e4a955c..24a90ba 100644
--- a/HTMLtree.c
+++ b/HTMLtree.c
@@ -84,13 +84,15 @@
     }
     xmlBufferWriteChar(buf, " ");
     xmlBufferWriteCHAR(buf, cur->name);
-    value = xmlNodeListGetString(doc, cur->children, 0);
-    if (value) {
-	xmlBufferWriteChar(buf, "=");
-	xmlBufferWriteQuotedString(buf, value);
-	xmlFree(value);
-    } else  {
-	xmlBufferWriteChar(buf, "=\"\"");
+    if (cur->children != NULL) {
+	value = xmlNodeListGetString(doc, cur->children, 0);
+	if (value) {
+	    xmlBufferWriteChar(buf, "=");
+	    xmlBufferWriteQuotedString(buf, value);
+	    xmlFree(value);
+	} else  {
+	    xmlBufferWriteChar(buf, "=\"\"");
+	}
     }
 }
 
diff --git a/Makefile.am b/Makefile.am
index 74624da..3f4b003 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -86,12 +86,14 @@
 
 check-local: tests
 
-install-data: $(srcdir)/libxml
-
 $(srcdir)/libxml:
 	-$(RM) $(srcdir)/libxml
 	ln -s $(srcdir)/. $(srcdir)/libxml
 
+install-data: $(srcdir)/libxml
+
+$(libxml_la_SOURCES): $(srcdir)/libxml
+
 testall : tests SVGtests SAXtests XPathtests XMLenttests
 
 tests: XMLtests HTMLtests Validtests
diff --git a/README b/README
index 2746bfe..cad4d77 100644
--- a/README
+++ b/README
@@ -4,6 +4,8 @@
 Full documentation is available on-line at
     http://xmlsoft.org/
 
+This code is released under the LGPL and the W3C IPR
+
 A mailing-list is available, to subscribe:
     echo "subscribe xml" | mail majordomo@rufus.w3.org
 
diff --git a/SAX.c b/SAX.c
index dace305..ee3af39 100644
--- a/SAX.c
+++ b/SAX.c
@@ -24,6 +24,7 @@
 #include <libxml/debugXML.h>
 #include <libxml/xmlIO.h>
 #include <libxml/SAX.h>
+#include <libxml/uri.h>
 
 /* #define DEBUG_SAX */
 /* #define DEBUG_SAX_TREE */
@@ -193,6 +194,7 @@
 	int oldwellFormed;
 	xmlParserInputPtr input = NULL;
 	xmlCharEncoding enc;
+	xmlCharEncoding oldcharset;
 
 	/*
 	 * Ask the Entity resolver to load the damn thing
@@ -214,6 +216,7 @@
 	oldinputMax = ctxt->inputMax;
 	oldinputTab = ctxt->inputTab;
 	oldwellFormed = ctxt->wellFormed;
+	oldcharset = ctxt->charset;
 
 	ctxt->inputTab = (xmlParserInputPtr *)
 	                 xmlMalloc(5 * sizeof(xmlParserInputPtr));
@@ -227,6 +230,7 @@
 	    ctxt->inputNr = oldinputNr;
 	    ctxt->inputMax = oldinputMax;
 	    ctxt->inputTab = oldinputTab;
+	    ctxt->charset = oldcharset;
 	    return;
 	}
 	ctxt->inputNr = 0;
@@ -269,6 +273,7 @@
 	ctxt->inputNr = oldinputNr;
 	ctxt->inputMax = oldinputMax;
 	ctxt->inputTab = oldinputTab;
+	ctxt->charset = oldcharset;
 	/* ctxt->wellFormed = oldwellFormed; */
     }
 }
@@ -604,6 +609,14 @@
 	ctxt->myDoc->encoding = ctxt->encoding;
 	ctxt->encoding = NULL;
     }
+    if ((ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) &&
+	(ctxt->myDoc->encoding == NULL)) {
+	ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding);
+    }
+    if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) &&
+	(ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) {
+	ctxt->myDoc->charset = ctxt->charset;
+    }
 }
 
 /**
@@ -640,7 +653,10 @@
     /*
      * Do the last stave of the attribute normalization
      */
-    nval = xmlValidNormalizeAttributeValue(ctxt->myDoc,
+    if (ctxt->html)
+	nval = NULL;
+    else
+	nval = xmlValidNormalizeAttributeValue(ctxt->myDoc,
 			       ctxt->node, fullname, value);
     if (nval != NULL)
 	value = nval;
@@ -648,9 +664,25 @@
     /*
      * Check whether it's a namespace definition
      */
-    if ((ns == NULL) &&
+    if ((!ctxt->html) && (ns == NULL) &&
         (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
         (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
+	xmlURIPtr uri;
+
+	uri = xmlParseURI((const char *)value);
+	if (uri == NULL) {
+	    if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
+		ctxt->sax->warning(ctxt->userData, 
+		     "nmlns: %s not a valid URI\n", value);
+	} else {
+	    if (uri->scheme == NULL) {
+		if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
+		    ctxt->sax->warning(ctxt->userData, 
+			 "nmlns: URI %s is not absolute\n", value);
+	    }
+	    xmlFreeURI(uri);
+	}
+
 	/* a default namespace definition */
 	xmlNewNs(ctxt->node, value, NULL);
 	if (name != NULL) 
@@ -659,7 +691,8 @@
 	    xmlFree(nval);
 	return;
     }
-    if ((ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
+    if ((!ctxt->html) &&
+	(ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
         (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
 	/*
 	 * Validate also for namespace decls, they are attributes from
@@ -701,7 +734,7 @@
 		    ret->last = tmp;
 		tmp = tmp->next;
 	    }
-	} else {
+	} else if (value != NULL) {
 	    ret->children = xmlNewDocText(ctxt->myDoc, value);
 	    ret->last = ret->children;
 	    if (ret->children != NULL)
@@ -709,7 +742,7 @@
 	}
     }
 
-    if (ctxt->validate && ctxt->wellFormed &&
+    if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
         ctxt->myDoc && ctxt->myDoc->intSubset) {
 	
 	/*
@@ -817,6 +850,7 @@
     } else if (parent == NULL) {
         parent = ctxt->myDoc->children;
     }
+    ctxt->nodemem = -1;
 
     /*
      * We are parsing a new node.
@@ -845,46 +879,20 @@
     }
 
     /*
-     * If it's the Document root, finish the Dtd validation and
-     * check the document root element for validity
-     */
-    if ((ctxt->validate) && (ctxt->vctxt.finishDtd == 0)) {
-	ctxt->valid &= xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
-	ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
-	ctxt->vctxt.finishDtd = 1;
-    }
-    /*
      * process all the attributes whose name start with "xml"
      */
     if (atts != NULL) {
         i = 0;
 	att = atts[i++];
 	value = atts[i++];
-        while ((att != NULL) && (value != NULL)) {
-	    if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l'))
-		attribute(ctxt, att, value);
+	if (!ctxt->html) {
+	    while ((att != NULL) && (value != NULL)) {
+		if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l'))
+		    attribute(ctxt, att, value);
 
-	    att = atts[i++];
-	    value = atts[i++];
-	}
-    }
-
-    /*
-     * process all the other attributes
-     */
-    if (atts != NULL) {
-        i = 0;
-	att = atts[i++];
-	value = atts[i++];
-        while ((att != NULL) && (value != NULL)) {
-	    if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l'))
-		attribute(ctxt, att, value);
-
-	    /*
-	     * Next ones
-	     */
-	    att = atts[i++];
-	    value = atts[i++];
+		att = atts[i++];
+		value = atts[i++];
+	    }
 	}
     }
 
@@ -897,6 +905,43 @@
 	ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
     xmlSetNs(ret, ns);
 
+    /*
+     * process all the other attributes
+     */
+    if (atts != NULL) {
+        i = 0;
+	att = atts[i++];
+	value = atts[i++];
+	if (ctxt->html) {
+	    while (att != NULL) {
+		attribute(ctxt, att, value);
+		att = atts[i++];
+		value = atts[i++];
+	    }
+	} else {
+	    while ((att != NULL) && (value != NULL)) {
+		if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l'))
+		    attribute(ctxt, att, value);
+
+		/*
+		 * Next ones
+		 */
+		att = atts[i++];
+		value = atts[i++];
+	    }
+	}
+    }
+
+    /*
+     * If it's the Document root, finish the Dtd validation and
+     * check the document root element for validity
+     */
+    if ((ctxt->validate) && (ctxt->vctxt.finishDtd == 0)) {
+	ctxt->valid &= xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
+	ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
+	ctxt->vctxt.finishDtd = 1;
+    }
+
     if (prefix != NULL)
 	xmlFree(prefix);
     if (name != NULL)
@@ -932,6 +977,7 @@
       node_info.node = cur;
       xmlParserAddNodeInfo(ctxt, &node_info);
     }
+    ctxt->nodemem = -1;
 
     if (ctxt->validate && ctxt->wellFormed &&
         ctxt->myDoc && ctxt->myDoc->intSubset)
@@ -1008,14 +1054,62 @@
 #ifdef DEBUG_SAX_TREE
     fprintf(stderr, "add chars to %s \n", ctxt->node->name);
 #endif
-    if (lastChild == NULL)
+
+    /*
+     * Here we needed an accelerator mechanism in case of very large
+     * elements. Use an attribute in the structure !!!
+     */
+    if (lastChild == NULL) {
+	/* first node, first time */
 	xmlNodeAddContentLen(ctxt->node, ch, len);
-    else {
-	if (xmlNodeIsText(lastChild))
+#ifndef XML_USE_BUFFER_CONTENT
+	if (ctxt->node->children != NULL) {
+	    ctxt->nodelen = len;
+	    ctxt->nodemem = len + 1;
+	}
+#endif
+    } else {
+	if (xmlNodeIsText(lastChild)) {
+#ifndef XML_USE_BUFFER_CONTENT
+	    /*
+	     * The whole point of maintaining nodelen and nodemem,
+	     * xmlTextConcat is too costly, i.e. compute lenght,
+	     * reallocate a new buffer, move data, append ch. Here
+	     * We try to minimaze realloc() uses and avoid copying
+	     * and recomputing lenght over and over.
+	     */
+	    if (ctxt->nodelen + len >= ctxt->nodemem) {
+		xmlChar *newbuf;
+		int size;
+
+		size = ctxt->nodemem + len;
+		size *= 2;
+                newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
+		if (newbuf == NULL) {
+		    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
+			ctxt->sax->error(ctxt->userData, 
+			     "SAX.characters(): out of memory\n");
+		    return;
+		}
+		ctxt->nodemem = size;
+		lastChild->content = newbuf;
+	    }
+	    memcpy(&lastChild->content[ctxt->nodelen], ch, len);
+	    ctxt->nodelen += len;
+	    lastChild->content[ctxt->nodelen] = 0;
+#else
 	    xmlTextConcat(lastChild, ch, len);
-	else {
+#endif
+	} else {
+	    /* Mixed content, first time */
 	    lastChild = xmlNewTextLen(ch, len);
 	    xmlAddChild(ctxt->node, lastChild);
+#ifndef XML_USE_BUFFER_CONTENT
+	    if (ctxt->node->children != NULL) {
+		ctxt->nodelen = len;
+		ctxt->nodemem = len + 1;
+	    }
+#endif
 	}
     }
 }
diff --git a/TODO b/TODO
index 2b4ae5e..8545e1a 100644
--- a/TODO
+++ b/TODO
@@ -6,14 +6,17 @@
 TODO:
 =====
 
-- xmlSwitchToEncoding() need a rewrite for correct handling of conversion
-  error code conditions.
+- If the internal encoding is not UTF8 saving to a given encoding doesn't
+  work
+- problem when parsing hrefs with & with the HTML parser (IRC ac)
 - DOM needs
   xmlAttrPtr xmlNewDocProp(xmlDocPtr doc, const xmlChar *name, const xmlChar *value)
   int xmlPruneProp(xmlNodePtr node, xmlAtttrPtr attr);
+- General checking of DTD validation in presence of namespaces ... hairy
+  mostly done
 - Fix DTD + namespace validity problem
   "Not valid: root and DtD name do not match 'ROOT' and 'prefix:ROOT'"
-- add support for the trick from Henry conf/sun/valid/empty.xml
+  mostly done
 - Correct standalone checking/emitting (hard)
   2.9 Standalone Document Declaration
 - Better checking of external parsed entities TAG 1234
@@ -24,9 +27,10 @@
 - Handle undefined namespaces in entity contents better ... at least
   issue a warning
 - Issue warning when using non-absolute namespaces URI.
-- General checking of DTD validation in presence of namespaces ... hairy
 - fix --disable-corba configure switch handling, and use XML_WITHOUT_CORBA
   not WITHOUT_CORBA flag
+- the html parser should add <head> and <body> if they don't exist
+- Command to force the parser to stop parsing and ignore the rest of the file.
 
 TODO:
 =====
@@ -92,6 +96,9 @@
 Done:
 =====
 
+- support for HTML empty attributes like <hr noshade>
+- plugged iconv() in for support of a large set of encodings.
+- xmlSwitchToEncoding() rewrite done
 - URI checkings (no fragments) rfc2396.txt
 - Added a clean mechanism for overload or added input methods:
   xmlRegisterInputCallbacks()
diff --git a/debugXML.c b/debugXML.c
index 6a271b8..88158d8 100644
--- a/debugXML.c
+++ b/debugXML.c
@@ -1326,7 +1326,7 @@
         if ((node->type == XML_DOCUMENT_NODE) ||
             (node->type == XML_HTML_DOCUMENT_NODE)) {
 	    node = ((xmlDocPtr) node)->children;
-        } else if (node->children != NULL) {
+        } else if ((node->children != NULL) && (node->type != XML_ENTITY_REF_NODE)) {
 	    /* deep first */
 	    node = node->children;
 	    indent++;
diff --git a/doc/html/gnome-xml-tree.html b/doc/html/gnome-xml-tree.html
index e334988..c1a4e98 100644
--- a/doc/html/gnome-xml-tree.html
+++ b/doc/html/gnome-xml-tree.html
@@ -8137,1314 +8137,4 @@
 >xmlChar</A
 >*    xmlNodeGetContent               (<A
 HREF="gnome-xml-tree.html#XMLNODEPTR"
->xmlNodePtr</A
-> cur);</PRE
-></TD
-></TR
-></TABLE
-><P
->Read the value of a node, this can be either the text carried
-directly by this node if it's a TEXT node or the aggregate string
-of the values carried by this node child's (TEXT and ENTITY_REF).
-Entity references are substitued.</P
-><P
-></P
-><DIV
-CLASS="INFORMALTABLE"
-><P
-></P
-><TABLE
-BORDER="0"
-WIDTH="100%"
-BGCOLOR="#FFD0D0"
-CELLSPACING="0"
-CELLPADDING="4"
-CLASS="CALSTABLE"
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->cur</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><I
-CLASS="EMPHASIS"
->Returns</I
-> :</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-></TABLE
-><P
-></P
-></DIV
-></DIV
-><HR><DIV
-CLASS="REFSECT2"
-><A
-NAME="AEN4780"
-></A
-><H3
-><A
-NAME="XMLNODEGETLANG"
-></A
->xmlNodeGetLang ()</H3
-><TABLE
-BORDER="0"
-BGCOLOR="#D6E8FF"
-WIDTH="100%"
-CELLPADDING="6"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
-><A
-HREF="gnome-xml-tree.html#XMLCHAR"
->xmlChar</A
->*    xmlNodeGetLang                  (<A
-HREF="gnome-xml-tree.html#XMLNODEPTR"
->xmlNodePtr</A
-> cur);</PRE
-></TD
-></TR
-></TABLE
-><P
->Searches the language of a node, i.e. the values of the xml:lang
-attribute or the one carried by the nearest ancestor.</P
-><P
-></P
-><DIV
-CLASS="INFORMALTABLE"
-><P
-></P
-><TABLE
-BORDER="0"
-WIDTH="100%"
-BGCOLOR="#FFD0D0"
-CELLSPACING="0"
-CELLPADDING="4"
-CLASS="CALSTABLE"
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->cur</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><I
-CLASS="EMPHASIS"
->Returns</I
-> :</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-></TABLE
-><P
-></P
-></DIV
-></DIV
-><HR><DIV
-CLASS="REFSECT2"
-><A
-NAME="AEN4801"
-></A
-><H3
-><A
-NAME="XMLNODESETLANG"
-></A
->xmlNodeSetLang ()</H3
-><TABLE
-BORDER="0"
-BGCOLOR="#D6E8FF"
-WIDTH="100%"
-CELLPADDING="6"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->void        xmlNodeSetLang                  (<A
-HREF="gnome-xml-tree.html#XMLNODEPTR"
->xmlNodePtr</A
-> cur,
-                                             const <A
-HREF="gnome-xml-tree.html#XMLCHAR"
->xmlChar</A
-> *lang);</PRE
-></TD
-></TR
-></TABLE
-><P
->Set the language of a node, i.e. the values of the xml:lang
-attribute.</P
-><P
-></P
-><DIV
-CLASS="INFORMALTABLE"
-><P
-></P
-><TABLE
-BORDER="0"
-WIDTH="100%"
-BGCOLOR="#FFD0D0"
-CELLSPACING="0"
-CELLPADDING="4"
-CLASS="CALSTABLE"
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->cur</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->lang</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-></TABLE
-><P
-></P
-></DIV
-></DIV
-><HR><DIV
-CLASS="REFSECT2"
-><A
-NAME="AEN4822"
-></A
-><H3
-><A
-NAME="XMLREMOVEPROP"
-></A
->xmlRemoveProp ()</H3
-><TABLE
-BORDER="0"
-BGCOLOR="#D6E8FF"
-WIDTH="100%"
-CELLPADDING="6"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->int         xmlRemoveProp                   (<A
-HREF="gnome-xml-tree.html#XMLATTRPTR"
->xmlAttrPtr</A
-> attr);</PRE
-></TD
-></TR
-></TABLE
-><P
->Unlink and free one attribute, all the content is freed too
-Note this doesn't work for namespace definition attributes</P
-><P
-></P
-><DIV
-CLASS="INFORMALTABLE"
-><P
-></P
-><TABLE
-BORDER="0"
-WIDTH="100%"
-BGCOLOR="#FFD0D0"
-CELLSPACING="0"
-CELLPADDING="4"
-CLASS="CALSTABLE"
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->attr</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><I
-CLASS="EMPHASIS"
->Returns</I
-> :</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-></TABLE
-><P
-></P
-></DIV
-></DIV
-><HR><DIV
-CLASS="REFSECT2"
-><A
-NAME="AEN4842"
-></A
-><H3
-><A
-NAME="XMLREMOVENODE"
-></A
->xmlRemoveNode ()</H3
-><TABLE
-BORDER="0"
-BGCOLOR="#D6E8FF"
-WIDTH="100%"
-CELLPADDING="6"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->int         xmlRemoveNode                   (<A
-HREF="gnome-xml-tree.html#XMLNODEPTR"
->xmlNodePtr</A
-> node);</PRE
-></TD
-></TR
-></TABLE
-><P
-></P
-><DIV
-CLASS="INFORMALTABLE"
-><P
-></P
-><TABLE
-BORDER="0"
-WIDTH="100%"
-BGCOLOR="#FFD0D0"
-CELLSPACING="0"
-CELLPADDING="4"
-CLASS="CALSTABLE"
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->node</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><I
-CLASS="EMPHASIS"
->Returns</I
-> :</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-></TABLE
-><P
-></P
-></DIV
-></DIV
-><HR><DIV
-CLASS="REFSECT2"
-><A
-NAME="AEN4861"
-></A
-><H3
-><A
-NAME="XMLBUFFERWRITECHAR"
-></A
->xmlBufferWriteCHAR ()</H3
-><TABLE
-BORDER="0"
-BGCOLOR="#D6E8FF"
-WIDTH="100%"
-CELLPADDING="6"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->void        xmlBufferWriteCHAR              (<A
-HREF="gnome-xml-tree.html#XMLBUFFERPTR"
->xmlBufferPtr</A
-> buf,
-                                             const <A
-HREF="gnome-xml-tree.html#XMLCHAR"
->xmlChar</A
-> *string);</PRE
-></TD
-></TR
-></TABLE
-><P
->routine which manage and grows an output buffer. This one add
-xmlChars at the end of the buffer.</P
-><P
-></P
-><DIV
-CLASS="INFORMALTABLE"
-><P
-></P
-><TABLE
-BORDER="0"
-WIDTH="100%"
-BGCOLOR="#FFD0D0"
-CELLSPACING="0"
-CELLPADDING="4"
-CLASS="CALSTABLE"
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->buf</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->string</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-></TABLE
-><P
-></P
-></DIV
-></DIV
-><HR><DIV
-CLASS="REFSECT2"
-><A
-NAME="AEN4882"
-></A
-><H3
-><A
-NAME="XMLBUFFERWRITECHAR"
-></A
->xmlBufferWriteChar ()</H3
-><TABLE
-BORDER="0"
-BGCOLOR="#D6E8FF"
-WIDTH="100%"
-CELLPADDING="6"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->void        xmlBufferWriteChar              (<A
-HREF="gnome-xml-tree.html#XMLBUFFERPTR"
->xmlBufferPtr</A
-> buf,
-                                             const char *string);</PRE
-></TD
-></TR
-></TABLE
-><P
->routine which manage and grows an output buffer. This one add
-C chars at the end of the array.</P
-><P
-></P
-><DIV
-CLASS="INFORMALTABLE"
-><P
-></P
-><TABLE
-BORDER="0"
-WIDTH="100%"
-BGCOLOR="#FFD0D0"
-CELLSPACING="0"
-CELLPADDING="4"
-CLASS="CALSTABLE"
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->buf</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->string</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-></TABLE
-><P
-></P
-></DIV
-></DIV
-><HR><DIV
-CLASS="REFSECT2"
-><A
-NAME="AEN4902"
-></A
-><H3
-><A
-NAME="XMLBUFFERWRITEQUOTEDSTRING"
-></A
->xmlBufferWriteQuotedString ()</H3
-><TABLE
-BORDER="0"
-BGCOLOR="#D6E8FF"
-WIDTH="100%"
-CELLPADDING="6"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->void        xmlBufferWriteQuotedString      (<A
-HREF="gnome-xml-tree.html#XMLBUFFERPTR"
->xmlBufferPtr</A
-> buf,
-                                             const <A
-HREF="gnome-xml-tree.html#XMLCHAR"
->xmlChar</A
-> *string);</PRE
-></TD
-></TR
-></TABLE
-><P
->routine which manage and grows an output buffer. This one writes
-a quoted or double quoted xmlChar string, checking first if it holds
-quote or double-quotes internally</P
-><P
-></P
-><DIV
-CLASS="INFORMALTABLE"
-><P
-></P
-><TABLE
-BORDER="0"
-WIDTH="100%"
-BGCOLOR="#FFD0D0"
-CELLSPACING="0"
-CELLPADDING="4"
-CLASS="CALSTABLE"
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->buf</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->string</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-></TABLE
-><P
-></P
-></DIV
-></DIV
-><HR><DIV
-CLASS="REFSECT2"
-><A
-NAME="AEN4923"
-></A
-><H3
-><A
-NAME="XMLDOCDUMPMEMORY"
-></A
->xmlDocDumpMemory ()</H3
-><TABLE
-BORDER="0"
-BGCOLOR="#D6E8FF"
-WIDTH="100%"
-CELLPADDING="6"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->void        xmlDocDumpMemory                (<A
-HREF="gnome-xml-tree.html#XMLDOCPTR"
->xmlDocPtr</A
-> cur,
-                                             <A
-HREF="gnome-xml-tree.html#XMLCHAR"
->xmlChar</A
-> **mem,
-                                             int *size);</PRE
-></TD
-></TR
-></TABLE
-><P
->Dump an XML document in memory and return the xmlChar * and it's size.
-It's up to the caller to free the memory.</P
-><P
-></P
-><DIV
-CLASS="INFORMALTABLE"
-><P
-></P
-><TABLE
-BORDER="0"
-WIDTH="100%"
-BGCOLOR="#FFD0D0"
-CELLSPACING="0"
-CELLPADDING="4"
-CLASS="CALSTABLE"
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->cur</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->mem</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->size</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-></TABLE
-><P
-></P
-></DIV
-></DIV
-><HR><DIV
-CLASS="REFSECT2"
-><A
-NAME="AEN4948"
-></A
-><H3
-><A
-NAME="XMLDOCDUMP"
-></A
->xmlDocDump ()</H3
-><TABLE
-BORDER="0"
-BGCOLOR="#D6E8FF"
-WIDTH="100%"
-CELLPADDING="6"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->void        xmlDocDump                      (<GTKDOCLINK
-HREF="FILE"
->FILE</GTKDOCLINK
-> *f,
-                                             <A
-HREF="gnome-xml-tree.html#XMLDOCPTR"
->xmlDocPtr</A
-> cur);</PRE
-></TD
-></TR
-></TABLE
-><P
->Dump an XML document to an open FILE.</P
-><P
-></P
-><DIV
-CLASS="INFORMALTABLE"
-><P
-></P
-><TABLE
-BORDER="0"
-WIDTH="100%"
-BGCOLOR="#FFD0D0"
-CELLSPACING="0"
-CELLPADDING="4"
-CLASS="CALSTABLE"
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->f</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->cur</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-></TABLE
-><P
-></P
-></DIV
-></DIV
-><HR><DIV
-CLASS="REFSECT2"
-><A
-NAME="AEN4969"
-></A
-><H3
-><A
-NAME="XMLSAVEFILE"
-></A
->xmlSaveFile ()</H3
-><TABLE
-BORDER="0"
-BGCOLOR="#D6E8FF"
-WIDTH="100%"
-CELLPADDING="6"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->int         xmlSaveFile                     (const char *filename,
-                                             <A
-HREF="gnome-xml-tree.html#XMLDOCPTR"
->xmlDocPtr</A
-> cur);</PRE
-></TD
-></TR
-></TABLE
-><P
->Dump an XML document to a file. Will use compression if
-compiled in and enabled. If <TT
-CLASS="PARAMETER"
-><I
->filename</I
-></TT
-> is "-" the stdout file is
-used.</P
-><P
-></P
-><DIV
-CLASS="INFORMALTABLE"
-><P
-></P
-><TABLE
-BORDER="0"
-WIDTH="100%"
-BGCOLOR="#FFD0D0"
-CELLSPACING="0"
-CELLPADDING="4"
-CLASS="CALSTABLE"
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->filename</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->cur</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><I
-CLASS="EMPHASIS"
->Returns</I
-> :</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-></TABLE
-><P
-></P
-></DIV
-></DIV
-><HR><DIV
-CLASS="REFSECT2"
-><A
-NAME="AEN4994"
-></A
-><H3
-><A
-NAME="XMLGETDOCCOMPRESSMODE"
-></A
->xmlGetDocCompressMode ()</H3
-><TABLE
-BORDER="0"
-BGCOLOR="#D6E8FF"
-WIDTH="100%"
-CELLPADDING="6"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->int         xmlGetDocCompressMode           (<A
-HREF="gnome-xml-tree.html#XMLDOCPTR"
->xmlDocPtr</A
-> doc);</PRE
-></TD
-></TR
-></TABLE
-><P
->get the compression ratio for a document, ZLIB based</P
-><P
-></P
-><DIV
-CLASS="INFORMALTABLE"
-><P
-></P
-><TABLE
-BORDER="0"
-WIDTH="100%"
-BGCOLOR="#FFD0D0"
-CELLSPACING="0"
-CELLPADDING="4"
-CLASS="CALSTABLE"
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->doc</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><I
-CLASS="EMPHASIS"
->Returns</I
-> :</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-></TABLE
-><P
-></P
-></DIV
-></DIV
-><HR><DIV
-CLASS="REFSECT2"
-><A
-NAME="AEN5014"
-></A
-><H3
-><A
-NAME="XMLSETDOCCOMPRESSMODE"
-></A
->xmlSetDocCompressMode ()</H3
-><TABLE
-BORDER="0"
-BGCOLOR="#D6E8FF"
-WIDTH="100%"
-CELLPADDING="6"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->void        xmlSetDocCompressMode           (<A
-HREF="gnome-xml-tree.html#XMLDOCPTR"
->xmlDocPtr</A
-> doc,
-                                             int mode);</PRE
-></TD
-></TR
-></TABLE
-><P
->set the compression ratio for a document, ZLIB based
-Correct values: 0 (uncompressed) to 9 (max compression)</P
-><P
-></P
-><DIV
-CLASS="INFORMALTABLE"
-><P
-></P
-><TABLE
-BORDER="0"
-WIDTH="100%"
-BGCOLOR="#FFD0D0"
-CELLSPACING="0"
-CELLPADDING="4"
-CLASS="CALSTABLE"
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->doc</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->mode</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-></TABLE
-><P
-></P
-></DIV
-></DIV
-><HR><DIV
-CLASS="REFSECT2"
-><A
-NAME="AEN5034"
-></A
-><H3
-><A
-NAME="XMLGETCOMPRESSMODE"
-></A
->xmlGetCompressMode ()</H3
-><TABLE
-BORDER="0"
-BGCOLOR="#D6E8FF"
-WIDTH="100%"
-CELLPADDING="6"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->int         xmlGetCompressMode              (void);</PRE
-></TD
-></TR
-></TABLE
-><P
->get the default compression mode used, ZLIB based.</P
-><P
-></P
-><DIV
-CLASS="INFORMALTABLE"
-><P
-></P
-><TABLE
-BORDER="0"
-WIDTH="100%"
-BGCOLOR="#FFD0D0"
-CELLSPACING="0"
-CELLPADDING="4"
-CLASS="CALSTABLE"
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><I
-CLASS="EMPHASIS"
->Returns</I
-> :</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-></TABLE
-><P
-></P
-></DIV
-></DIV
-><HR><DIV
-CLASS="REFSECT2"
-><A
-NAME="AEN5049"
-></A
-><H3
-><A
-NAME="XMLSETCOMPRESSMODE"
-></A
->xmlSetCompressMode ()</H3
-><TABLE
-BORDER="0"
-BGCOLOR="#D6E8FF"
-WIDTH="100%"
-CELLPADDING="6"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->void        xmlSetCompressMode              (int mode);</PRE
-></TD
-></TR
-></TABLE
-><P
->set the default compression mode used, ZLIB based
-Correct values: 0 (uncompressed) to 9 (max compression)</P
-><P
-></P
-><DIV
-CLASS="INFORMALTABLE"
-><P
-></P
-><TABLE
-BORDER="0"
-WIDTH="100%"
-BGCOLOR="#FFD0D0"
-CELLSPACING="0"
-CELLPADDING="4"
-CLASS="CALSTABLE"
-><TR
-><TD
-WIDTH="20%"
-ALIGN="RIGHT"
-VALIGN="TOP"
-><TT
-CLASS="PARAMETER"
-><I
->mode</I
-></TT
->&nbsp;:</TD
-><TD
-WIDTH="80%"
-ALIGN="LEFT"
-VALIGN="TOP"
->&nbsp;</TD
-></TR
-></TABLE
-><P
-></P
-></DIV
-></DIV
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><BR
-CLEAR="all"><BR><TABLE
-WIDTH="100%"
-BORDER="0"
-BGCOLOR="#000000"
-CELLPADDING="1"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="25%"
-BGCOLOR="#C00000"
-ALIGN="left"
-><A
-HREF="gnome-xml-sax.html"
-><FONT
-COLOR="#FFFFFF"
-SIZE="3"
-><B
->&#60;&#60;&#60; Previous Page</B
-></FONT
-></A
-></TD
-><TD
-WIDTH="25%"
-BGCOLOR="#0000C0"
-ALIGN="center"
-><FONT
-COLOR="#FFFFFF"
-SIZE="3"
-><B
-><A
-HREF="book1.html"
-><FONT
-COLOR="#FFFFFF"
-SIZE="3"
-><B
->Home</B
-></FONT
-></A
-></B
-></FONT
-></TD
-><TD
-WIDTH="25%"
-BGCOLOR="#00C000"
-ALIGN="center"
-><FONT
-COLOR="#FFFFFF"
-SIZE="3"
-><B
-><A
-HREF="libxml-lib.html"
-><FONT
-COLOR="#FFFFFF"
-SIZE="3"
-><B
->Up</B
-></FONT
-></A
-></B
-></FONT
-></TD
-><TD
-WIDTH="25%"
-BGCOLOR="#C00000"
-ALIGN="right"
-><A
-HREF="gnome-xml-entities.html"
-><FONT
-COLOR="#FFFFFF"
-SIZE="3"
-><B
->Next Page &#62;&#62;&#62;</B
-></FONT
-></A
-></TD
-></TR
-><TR
-><TD
-COLSPAN="2"
-ALIGN="left"
-><FONT
-COLOR="#FFFFFF"
-SIZE="3"
-><B
->SAX</B
-></FONT
-></TD
-><TD
-COLSPAN="2"
-ALIGN="right"
-><FONT
-COLOR="#FFFFFF"
-SIZE="3"
-><B
->entities</B
-></FONT
-></TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
 >
\ No newline at end of file
diff --git a/encoding.c b/encoding.c
index 1a4c157..627f468 100644
--- a/encoding.c
+++ b/encoding.c
@@ -3,6 +3,7 @@
  *
  * Related specs: 
  * rfc2044        (UTF-8 and UTF-16) F. Yergeau Alis Technologies
+ * rfc2781        UTF-16, an encoding of ISO 10646, P. Hoffman, F. Yergeau
  * [ISO-10646]    UTF-8 and UTF-16 in Annexes
  * [ISO-8859-1]   ISO Latin-1 characters codes.
  * [UNICODE]      The Unicode Consortium, "The Unicode Standard --
@@ -66,6 +67,73 @@
  */
 
 /**
+ * xmlGetUTF8Char:
+ * @utf:  a sequence of UTF-8 encoded bytes
+ * @len:  a pointer to @bytes len
+ *
+ * Read one UTF8 Char from @utf
+ *
+ * Returns the char value or -1 in case of error and update @len with the
+ *        number of bytes used
+ */
+int
+xmlGetUTF8Char(const unsigned char *utf, int *len) {
+    unsigned int c;
+
+    if (utf == NULL)
+	goto error;
+    if (len == NULL)
+	goto error;
+    if (*len < 1)
+	goto error;
+
+    c = utf[0];
+    if (c & 0x80) {
+	if (*len < 2)
+	    goto error;
+	if ((utf[1] & 0xc0) != 0x80)
+	    goto error;
+	if ((c & 0xe0) == 0xe0) {
+	    if (*len < 3)
+		goto error;
+	    if ((utf[2] & 0xc0) != 0x80)
+		goto error;
+	    if ((c & 0xf0) == 0xf0) {
+		if (*len < 4)
+		    goto error;
+		if ((c & 0xf8) != 0xf0 || (utf[3] & 0xc0) != 0x80)
+		    goto error;
+		*len = 4;
+		/* 4-byte code */
+		c = (utf[0] & 0x7) << 18;
+		c |= (utf[1] & 0x3f) << 12;
+		c |= (utf[2] & 0x3f) << 6;
+		c |= utf[3] & 0x3f;
+	    } else {
+	      /* 3-byte code */
+		*len = 3;
+		c = (utf[0] & 0xf) << 12;
+		c |= (utf[1] & 0x3f) << 6;
+		c |= utf[2] & 0x3f;
+	    }
+	} else {
+	  /* 2-byte code */
+	    *len = 2;
+	    c = (utf[0] & 0x1f) << 6;
+	    c |= utf[1] & 0x3f;
+	}
+    } else {
+	/* 1-byte code */
+	*len = 1;
+    }
+    return(c);
+
+error:
+    *len = 0;
+    return(-1);
+}
+
+/**
  * xmlCheckUTF8: Check utf-8 string for legality.
  * @utf: Pointer to putative utf-8 encoded string.
  *
@@ -236,7 +304,7 @@
         (*inlenb)--;
     inlen = *inlenb / 2;
     inend = in + inlen;
-    while (in < inend) {
+    while ((in < inend) && (out - outstart + 5 < *outlen)) {
         if (xmlLittleEndian) {
 	    c= *in++;
 	} else {
@@ -246,9 +314,9 @@
 	    in++;
 	}
         if ((c & 0xFC00) == 0xD800) {    /* surrogates */
-            if (in >= inend) {           /* (in > inend) shouldn't happens */
-                break;
-            }
+	    if (in >= inend) {           /* (in > inend) shouldn't happens */
+		break;
+	    }
 	    if (xmlLittleEndian) {
 		d = *in++;
 	    } else {
@@ -317,6 +385,24 @@
     unsigned char *tmp;
     unsigned short tmp1, tmp2;
 
+    if (in == NULL) {
+        /*
+	 * initialization, add the Byte Order Mark
+	 */
+        if (*outlen >= 2) {
+	    outb[0] = 0xFF;
+	    outb[1] = 0xFE;
+	    *outlen = 2;
+	    *inlen = 0;
+#ifdef DEBUG_ENCODING
+            fprintf(stderr, "Added FFFE Byte Order Mark\n");
+#endif
+	    return(2);
+	}
+	*outlen = 0;
+	*inlen = 0;
+	return(0);
+    }
     outend = out + (*outlen / 2);
     while (in < inend) {
       d= *in++;
@@ -385,7 +471,7 @@
 	    break;
 	processed = in;
     }
-    *outlen = out - outstart;
+    *outlen = (out - outstart) * 2;
     *inlen = processed - in;
     return(0);
 }
@@ -509,6 +595,24 @@
     unsigned char *tmp;
     unsigned short tmp1, tmp2;
 
+    if (in == NULL) {
+        /*
+	 * initialization, add the Byte Order Mark
+	 */
+        if (*outlen >= 2) {
+	    outb[0] = 0xFE;
+	    outb[1] = 0xFF;
+	    *outlen = 2;
+	    *inlen = 0;
+#ifdef DEBUG_ENCODING
+            fprintf(stderr, "Added FEFF Byte Order Mark\n");
+#endif
+	    return(2);
+	}
+	*outlen = 0;
+	*inlen = 0;
+	return(0);
+    }
     outend = out + (*outlen / 2);
     while (in < inend) {
       d= *in++;
@@ -574,7 +678,7 @@
 	    break;
 	processed = in;
     }
-    *outlen = out - outstart;
+    *outlen = (out - outstart) * 2;
     *inlen = processed - in;
     return(0);
 }
@@ -695,6 +799,70 @@
     return(XML_CHAR_ENCODING_ERROR);
 }
 
+/**
+ * xmlGetCharEncodingName:
+ * @enc:  the encoding
+ *
+ * The "canonical" name for XML encoding.
+ * C.f. http://www.w3.org/TR/REC-xml#charencoding
+ * Section 4.3.3  Character Encoding in Entities
+ *
+ * Returns the canonical name for the given encoding
+ */
+
+const char*
+xmlGetCharEncodingName(xmlCharEncoding enc) {
+    switch (enc) {
+        case XML_CHAR_ENCODING_ERROR:
+	    return(NULL);
+        case XML_CHAR_ENCODING_NONE:
+	    return(NULL);
+        case XML_CHAR_ENCODING_UTF8:
+	    return("UTF-8");
+        case XML_CHAR_ENCODING_UTF16LE:
+	    return("UTF-16");
+        case XML_CHAR_ENCODING_UTF16BE:
+	    return("UTF-16");
+        case XML_CHAR_ENCODING_EBCDIC:
+            return("EBCDIC");
+        case XML_CHAR_ENCODING_UCS4LE:
+            return("ISO-10646-UCS-4");
+        case XML_CHAR_ENCODING_UCS4BE:
+            return("ISO-10646-UCS-4");
+        case XML_CHAR_ENCODING_UCS4_2143:
+            return("ISO-10646-UCS-4");
+        case XML_CHAR_ENCODING_UCS4_3412:
+            return("ISO-10646-UCS-4");
+        case XML_CHAR_ENCODING_UCS2:
+            return("ISO-10646-UCS-2");
+        case XML_CHAR_ENCODING_8859_1:
+	    return("ISO-8859-1");
+        case XML_CHAR_ENCODING_8859_2:
+	    return("ISO-8859-2");
+        case XML_CHAR_ENCODING_8859_3:
+	    return("ISO-8859-3");
+        case XML_CHAR_ENCODING_8859_4:
+	    return("ISO-8859-4");
+        case XML_CHAR_ENCODING_8859_5:
+	    return("ISO-8859-5");
+        case XML_CHAR_ENCODING_8859_6:
+	    return("ISO-8859-6");
+        case XML_CHAR_ENCODING_8859_7:
+	    return("ISO-8859-7");
+        case XML_CHAR_ENCODING_8859_8:
+	    return("ISO-8859-8");
+        case XML_CHAR_ENCODING_8859_9:
+	    return("ISO-8859-9");
+        case XML_CHAR_ENCODING_2022_JP:
+            return("ISO-2022-JP");
+        case XML_CHAR_ENCODING_SHIFT_JIS:
+            return("Shift-JIS");
+        case XML_CHAR_ENCODING_EUC_JP:
+            return("EUC-JP");
+    }
+    return(NULL);
+}
+
 /****************************************************************
  *								*
  *		Char encoding handlers				*
@@ -883,7 +1051,7 @@
             handler = xmlFindCharEncodingHandler("ebcdic");
             if (handler != NULL) return(handler);
 	    break;
-        case XML_CHAR_ENCODING_UCS4LE:
+        case XML_CHAR_ENCODING_UCS4BE:
             handler = xmlFindCharEncodingHandler("ISO-10646-UCS-4");
             if (handler != NULL) return(handler);
             handler = xmlFindCharEncodingHandler("UCS-4");
@@ -891,8 +1059,12 @@
             handler = xmlFindCharEncodingHandler("UCS4");
             if (handler != NULL) return(handler);
 	    break;
-        case XML_CHAR_ENCODING_UCS4BE:
-            handler = xmlFindCharEncodingHandler("UCS4BE");
+        case XML_CHAR_ENCODING_UCS4LE:
+            handler = xmlFindCharEncodingHandler("ISO-10646-UCS-4");
+            if (handler != NULL) return(handler);
+            handler = xmlFindCharEncodingHandler("UCS-4");
+            if (handler != NULL) return(handler);
+            handler = xmlFindCharEncodingHandler("UCS4");
             if (handler != NULL) return(handler);
 	    break;
         case XML_CHAR_ENCODING_UCS4_2143:
@@ -953,9 +1125,10 @@
  */
 xmlCharEncodingHandlerPtr
 xmlFindCharEncodingHandler(const char *name) {
+    xmlCharEncodingHandlerPtr enc;
+    xmlCharEncoding alias;
 #ifdef LIBXML_ICONV_ENABLED
     iconv_t icv_in, icv_out;
-    xmlCharEncodingHandlerPtr enc;
 #endif /* LIBXML_ICONV_ENABLED */
     char upper[100];
     int i;
@@ -964,6 +1137,9 @@
     if (name == NULL) return(xmlDefaultCharEncodingHandler);
     if (name[0] == 0) return(xmlDefaultCharEncodingHandler);
 
+    /*
+     * Check first for directly registered encoding names
+     */
     for (i = 0;i < 99;i++) {
         upper[i] = toupper(name[i]);
 	if (upper[i] == 0) break;
@@ -1002,9 +1178,23 @@
 	    fprintf(stderr, "iconv : problems with filters for '%s'\n", name);
     }
 #endif /* LIBXML_ICONV_ENABLED */
+
 #ifdef DEBUG_ENCODING
     fprintf(stderr, "No handler found for encoding %s\n", name);
 #endif
+
+    /*
+     * Fallback using the canonical names
+     */
+    alias = xmlParseCharEncoding(name);
+    if (alias != XML_CHAR_ENCODING_ERROR) {
+        const char* canon;
+        canon = xmlGetCharEncodingName(alias);
+        if ((canon != NULL) && (strcmp(name, canon))) {
+	    return(xmlFindCharEncodingHandler(canon));
+        }
+    }
+
     return(NULL);
 }
 
@@ -1040,8 +1230,13 @@
 	ret = iconv(cd,
 		&icv_in, &icv_inlen,
 		&icv_out, &icv_outlen);
-	*inlen -= icv_inlen;
-	*outlen -= icv_outlen;
+	if (in != NULL) {
+	    *inlen -= icv_inlen;
+	    *outlen -= icv_outlen;
+	} else {
+	    *inlen = 0;
+	    *outlen = 0;
+	}
 	if (icv_inlen != 0 || ret == (size_t) -1) {
 #ifdef EILSEQ
 		if (errno == EILSEQ) {
@@ -1067,6 +1262,91 @@
 #endif /* LIBXML_ICONV_ENABLED */
 
 /**
+ * xmlCharEncFirstLine:
+ * @handler:	char enconding transformation data structure
+ * @out:  an xmlBuffer for the output.
+ * @in:  an xmlBuffer for the input
+ *     
+ * Front-end for the encoding handler input function, but handle only
+ * the very first line, i.e. limit itself to 45 chars.
+ *     
+ * Returns the number of byte written if success, or 
+ *     -1 general error
+ *     -2 if the transcoding fails (for *in is not valid utf8 string or
+ *        the result of transformation can't fit into the encoding we want), or
+ */
+int
+xmlCharEncFirstLine(xmlCharEncodingHandler *handler, xmlBufferPtr out,
+                 xmlBufferPtr in) {
+    int ret = -2;
+    int written;
+    int toconv;
+
+    if (handler == NULL) return(-1);
+    if (out == NULL) return(-1);
+    if (in == NULL) return(-1);
+
+    written = out->size - out->use;
+    toconv = in->use;
+    if (toconv * 2 >= written) {
+        xmlBufferGrow(out, toconv);
+	written = out->size - out->use - 1;
+    }
+
+    /*
+     * echo '<?xml version="1.0" encoding="UCS4"?>' | wc -c => 38
+     * 45 chars should be sufficient to reach the end of the encoding
+     * decalration without going too far inside the document content.
+     */
+    written = 45;
+
+    if (handler->input != NULL) {
+	ret = handler->input(&out->content[out->use], &written,
+	                     in->content, &toconv);
+	xmlBufferShrink(in, toconv);
+	out->use += written;
+	out->content[out->use] = 0;
+    }
+#ifdef LIBXML_ICONV_ENABLED
+    else if (handler->iconv_in != NULL) {
+	ret = xmlIconvWrapper(handler->iconv_in, &out->content[out->use],
+	                      &written, in->content, &toconv);
+	xmlBufferShrink(in, toconv);
+	out->use += written;
+	out->content[out->use] = 0;
+	if (ret == -1) ret = -3;
+    }
+#endif /* LIBXML_ICONV_ENABLED */
+#ifdef DEBUG_ENCODING
+    switch (ret) {
+        case 0:
+	    fprintf(stderr, "converted %d bytes to %d bytes of input\n",
+	            toconv, written);
+	    break;
+        case -1:
+	    fprintf(stderr,"converted %d bytes to %d bytes of input, %d left\n",
+	            toconv, written, in->use);
+	    break;
+        case -2:
+	    fprintf(stderr, "input conversion failed due to input error\n");
+	    break;
+        case -3:
+	    fprintf(stderr,"converted %d bytes to %d bytes of input, %d left\n",
+	            toconv, written, in->use);
+	    break;
+	default:
+	    fprintf(stderr,"Unknown input conversion failed %d\n", ret);
+    }
+#endif
+    /*
+     * Ignore when input buffer is not on a boundary
+     */
+    if (ret == -3) ret = 0;
+    if (ret == -1) ret = 0;
+    return(ret);
+}
+
+/**
  * xmlCharEncInFunc:
  * @handler:	char enconding transformation data structure
  * @out:  an xmlBuffer for the output.
@@ -1113,8 +1393,8 @@
 	if (ret == -1) ret = -3;
     }
 #endif /* LIBXML_ICONV_ENABLED */
-#ifdef DEBUG_ENCODING
     switch (ret) {
+#ifdef DEBUG_ENCODING
         case 0:
 	    fprintf(stderr, "converted %d bytes to %d bytes of input\n",
 	            toconv, written);
@@ -1123,17 +1403,17 @@
 	    fprintf(stderr,"converted %d bytes to %d bytes of input, %d left\n",
 	            toconv, written, in->use);
 	    break;
-        case -2:
-	    fprintf(stderr, "input conversion failed due to input error\n");
-	    break;
         case -3:
 	    fprintf(stderr,"converted %d bytes to %d bytes of input, %d left\n",
 	            toconv, written, in->use);
 	    break;
-	default:
-	    fprintf(stderr,"Unknown input conversion failed %d\n", ret);
-    }
 #endif
+        case -2:
+	    fprintf(stderr, "input conversion failed due to input error\n");
+	    fprintf(stderr, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
+		    in->content[0], in->content[1],
+		    in->content[2], in->content[3]);
+    }
     /*
      * Ignore when input buffer is not on a boundary
      */
@@ -1148,6 +1428,11 @@
  * @in:  an xmlBuffer for the input
  *     
  * Generic front-end for the encoding handler output function
+ * a first call with @in == NULL has to be made firs to initiate the 
+ * output in case of non-stateless encoding needing to initiate their
+ * state or the output (like the BOM in UTF16).
+ * In case of UTF8 sequence conversion errors for the given encoder,
+ * the content will be automatically remapped to a CharRef sequence.
  *     
  * Returns the number of byte written if success, or 
  *     -1 general error
@@ -1160,12 +1445,43 @@
     int ret = -2;
     int written;
     int toconv;
+    int output = 0;
 
     if (handler == NULL) return(-1);
     if (out == NULL) return(-1);
-    if (in == NULL) return(-1);
 
+retry:
+    
     written = out->size - out->use;
+
+    /*
+     * First specific handling of in = NULL, i.e. the initialization call
+     */
+    if (in == NULL) {
+        toconv = 0;
+	if (handler->output != NULL) {
+	    ret = handler->output(&out->content[out->use], &written,
+				  NULL, &toconv);
+	    out->use += written;
+	    out->content[out->use] = 0;
+	}
+#ifdef LIBXML_ICONV_ENABLED
+	else if (handler->iconv_out != NULL) {
+	    ret = xmlIconvWrapper(handler->iconv_out, &out->content[out->use],
+				  &written, NULL, &toconv);
+	    out->use += written;
+	    out->content[out->use] = 0;
+	}
+#endif /* LIBXML_ICONV_ENABLED */
+#ifdef DEBUG_ENCODING
+	fprintf(stderr, "initialized encoder\n");
+#endif
+        return(0);
+    }
+
+    /*
+     * Convertion itself.
+     */
     toconv = in->use;
     if (toconv * 2 >= written) {
         xmlBufferGrow(out, toconv * 2);
@@ -1173,7 +1489,7 @@
     }
     if (handler->output != NULL) {
 	ret = handler->output(&out->content[out->use], &written,
-	                     in->content, &toconv);
+	                      in->content, &toconv);
 	xmlBufferShrink(in, toconv);
 	out->use += written;
 	out->content[out->use] = 0;
@@ -1188,8 +1504,14 @@
 	if (ret == -1) ret = -3;
     }
 #endif /* LIBXML_ICONV_ENABLED */
-#ifdef DEBUG_ENCODING
+
+    if (ret >= 0) output += ret;
+
+    /*
+     * Attempt to handle error cases
+     */
     switch (ret) {
+#ifdef DEBUG_ENCODING
         case 0:
 	    fprintf(stderr, "converted %d bytes to %d bytes of output\n",
 	            toconv, written);
@@ -1197,17 +1519,45 @@
         case -1:
 	    fprintf(stderr, "output conversion failed by lack of space\n");
 	    break;
-        case -2:
-	    fprintf(stderr, "output conversion failed due to output error\n");
-	    break;
         case -3:
 	    fprintf(stderr,"converted %d bytes to %d bytes of output %d left\n",
 	            toconv, written, in->use);
 	    break;
-	default:
-	    fprintf(stderr,"Unknown output conversion failed %d\n", ret);
-    }
 #endif
+        case -2: {
+	    int len = in->use;
+	    const char *utf = (const char *) in->content;
+	    int cur;
+
+	    cur = xmlGetUTF8Char(utf, &len);
+	    if (cur > 0) {
+		xmlChar charref[20];
+
+#ifdef DEBUG_ENCODING
+		fprintf(stderr, "handling output conversion error\n");
+		fprintf(stderr, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
+			in->content[0], in->content[1],
+			in->content[2], in->content[3]);
+#endif
+		/*
+		 * Removes the UTF8 sequence, and replace it by a charref
+		 * and continue the transcoding phase, hoping the error
+		 * did not mangle the encoder state.
+		 */
+		sprintf(charref, "&#x%X;", cur);
+		xmlBufferShrink(in, len);
+		xmlBufferAddHead(in, charref, -1);
+
+		goto retry;
+	    } else {
+		fprintf(stderr, "output conversion failed due to conv error\n");
+		fprintf(stderr, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
+			in->content[0], in->content[1],
+			in->content[2], in->content[3]);
+	    }
+	    break;
+	}
+    }
     return(ret);
 }
 
diff --git a/encoding.h b/encoding.h
index f6edbf2..ce0ab75 100644
--- a/encoding.h
+++ b/encoding.h
@@ -102,6 +102,8 @@
  *
  * Take a block of UTF-8 chars in and try to convert it to an other
  * encoding.
+ * Note: a first call designed to produce heading info is called with
+ * in = NULL. If stateful this should also initialize the encoder state
  *
  * Returns the number of byte written, or -1 by lack of space, or -2
  *     if the transcoding failed.
@@ -136,6 +138,7 @@
 xmlCharEncoding xmlDetectCharEncoding	(const unsigned char* in,
 					 int len);
 xmlCharEncoding xmlParseCharEncoding	(const char* name);
+const char*	xmlGetCharEncodingName	(xmlCharEncoding enc);
 xmlCharEncodingHandlerPtr xmlGetCharEncodingHandler(xmlCharEncoding enc);
 xmlCharEncodingHandlerPtr xmlFindCharEncodingHandler(const char *name);
 int	xmlCheckUTF8			(const unsigned char *utf);
@@ -147,6 +150,9 @@
 int	xmlCharEncInFunc		(xmlCharEncodingHandler *handler,
 					 xmlBufferPtr out,
 					 xmlBufferPtr in);
+int	xmlCharEncFirstLine		(xmlCharEncodingHandler *handler,
+					 xmlBufferPtr out,
+					 xmlBufferPtr in);
 int	xmlCharEncCloseFunc		(xmlCharEncodingHandler *handler);
 
 #ifdef __cplusplus
diff --git a/entities.c b/entities.c
index 15247a2..c541d67 100644
--- a/entities.c
+++ b/entities.c
@@ -946,6 +946,86 @@
 }
 
 /**
+ * xmlEncodeSpecialChars:
+ * @doc:  the document containing the string
+ * @input:  A string to convert to XML.
+ *
+ * Do a global encoding of a string, replacing the predefined entities
+ * this routine is reentrant, and result must be deallocated.
+ *
+ * Returns A newly allocated string with the substitution done.
+ */
+xmlChar *
+xmlEncodeSpecialChars(xmlDocPtr doc, const xmlChar *input) {
+    const xmlChar *cur = input;
+    xmlChar *buffer = NULL;
+    xmlChar *out = NULL;
+    int buffer_size = 0;
+    int html = 0;
+
+    if (input == NULL) return(NULL);
+    if (doc != NULL)
+        html = (doc->type == XML_HTML_DOCUMENT_NODE);
+
+    /*
+     * allocate an translation buffer.
+     */
+    buffer_size = 1000;
+    buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
+    if (buffer == NULL) {
+	perror("malloc failed");
+	return(NULL);
+    }
+    out = buffer;
+
+    while (*cur != '\0') {
+        if (out - buffer > buffer_size - 10) {
+	    int index = out - buffer;
+
+	    growBufferReentrant();
+	    out = &buffer[index];
+	}
+
+	/*
+	 * By default one have to encode at least '<', '>', '"' and '&' !
+	 */
+	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 {
+	    /*
+	     * Works because on UTF-8, all extended sequences cannot
+	     * result in bytes in the ASCII range.
+	     */
+	    *out++ = *cur;
+	}
+	cur++;
+    }
+    *out++ = 0;
+    return(buffer);
+}
+
+/**
  * xmlCreateEntitiesTable:
  *
  * create and initialize an empty entities hash table.
diff --git a/entities.h b/entities.h
index f0ec731..c9bd003 100644
--- a/entities.h
+++ b/entities.h
@@ -106,6 +106,8 @@
 						 const xmlChar *input);
 xmlChar *		xmlEncodeEntitiesReentrant(xmlDocPtr doc,
 						 const xmlChar *input);
+xmlChar *		xmlEncodeSpecialChars	(xmlDocPtr doc,
+						 const xmlChar *input);
 xmlEntitiesTablePtr	xmlCreateEntitiesTable	(void);
 xmlEntitiesTablePtr	xmlCopyEntitiesTable	(xmlEntitiesTablePtr table);
 void			xmlFreeEntitiesTable	(xmlEntitiesTablePtr table);
diff --git a/example/Makefile.am b/example/Makefile.am
index 0978f95..ce7a8da 100644
--- a/example/Makefile.am
+++ b/example/Makefile.am
@@ -6,5 +6,9 @@
 
 LDADD = $(top_builddir)/libxml.la @Z_LIBS@
 
-$(top_builddir)/libxml.la:
+$(srcdir)/libxml:
+	-$(RM) $(srcdir)/libxml
+	ln -s $(srcdir)/. $(srcdir)/libxml
+
+$(top_builddir)/libxml.la: $(srcdir)/libxml
 	(cd .. ; $(MAKE))
diff --git a/example/gjobread.c b/example/gjobread.c
index ca38671..916fa53 100644
--- a/example/gjobread.c
+++ b/example/gjobread.c
@@ -10,12 +10,18 @@
 #include <string.h>
 #include <stdlib.h>
 
-#include <xmlmemory.h>
-#if defined(LIBXML_VERSION) && LIBXML_VERSION >= 20000
+/*
+ * This example should compile and run indifferently with libxml-1.8.8 +
+ * and libxml2-2.1.0 +
+ * Check the COMPAT comments below
+ */
+
+/*
+ * COMPAT using xml-config --cflags to get the include path this will
+ * work with both 
+ */
+#include <libxml/xmlmemory.h>
 #include <libxml/parser.h>
-#else 
-#include <gnome-xml/parser.h>
-#endif
 
 #define DEBUG(x) printf(x)
 
@@ -50,12 +56,13 @@
     memset(ret, 0, sizeof(person));
 
     /* We don't care what the top level element name is */
-    cur = cur->children;
+    /* COMPAT xmlChildrenNode is a macro unifying libxml1 and libxml2 names */
+    cur = cur->xmlChildrenNode;
     while (cur != NULL) {
         if ((!strcmp(cur->name, "Person")) && (cur->ns == ns))
-	    ret->name = xmlNodeListGetString(doc, cur->children, 1);
+	    ret->name = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
         if ((!strcmp(cur->name, "Email")) && (cur->ns == ns))
-	    ret->email = xmlNodeListGetString(doc, cur->children, 1);
+	    ret->email = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
 	cur = cur->next;
     }
 
@@ -108,7 +115,7 @@
     memset(ret, 0, sizeof(job));
 
     /* We don't care what the top level element name is */
-    cur = cur->children;
+    cur = cur->xmlChildrenNode;
     while (cur != NULL) {
         
         if ((!strcmp(cur->name, "Project")) && (cur->ns == ns)) {
@@ -118,9 +125,9 @@
 	    }
 	}
         if ((!strcmp(cur->name, "Application")) && (cur->ns == ns))
-	    ret->application = xmlNodeListGetString(doc, cur->children, 1);
+	    ret->application = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
         if ((!strcmp(cur->name, "Category")) && (cur->ns == ns))
-	    ret->category = xmlNodeListGetString(doc, cur->children, 1);
+	    ret->category = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
         if ((!strcmp(cur->name, "Contact")) && (cur->ns == ns))
 	    ret->contact = parsePerson(doc, ns, cur);
 	cur = cur->next;
@@ -173,8 +180,6 @@
      * Check the document is of the right kind
      */
     
-    //    cur = doc->root;
-    //    cur = doc->children;
     cur = xmlDocGetRootElement(doc);
     if (cur == NULL) {
         fprintf(stderr,"empty document\n");
@@ -209,8 +214,7 @@
      * Now, walk the tree.
      */
     /* First level we expect just Jobs */
-    //    cur = cur->children;
-    cur = cur -> children;
+    cur = cur->xmlChildrenNode;
     while ( cur && xmlIsBlankNode ( cur ) )
       {
 	cur = cur -> next;
@@ -229,7 +233,7 @@
     }
 
     /* Second level is a list of Job, but be laxist */
-    cur = cur->children;
+    cur = cur->xmlChildrenNode;
     while (cur != NULL) {
         if ((!strcmp(cur->name, "Job")) && (cur->ns == ns)) {
 	    job = parseJob(doc, ns, cur);
@@ -257,6 +261,9 @@
     int i;
     gJobPtr cur;
 
+    /* COMPAT: Do not genrate nodes for formatting spaces */
+    xmlKeepBlanksDefault(0);
+
     for (i = 1; i < argc ; i++) {
 	cur = parseGjobFile(argv[i]);
 	if ( cur )
diff --git a/include/libxml/encoding.h b/include/libxml/encoding.h
index f6edbf2..ce0ab75 100644
--- a/include/libxml/encoding.h
+++ b/include/libxml/encoding.h
@@ -102,6 +102,8 @@
  *
  * Take a block of UTF-8 chars in and try to convert it to an other
  * encoding.
+ * Note: a first call designed to produce heading info is called with
+ * in = NULL. If stateful this should also initialize the encoder state
  *
  * Returns the number of byte written, or -1 by lack of space, or -2
  *     if the transcoding failed.
@@ -136,6 +138,7 @@
 xmlCharEncoding xmlDetectCharEncoding	(const unsigned char* in,
 					 int len);
 xmlCharEncoding xmlParseCharEncoding	(const char* name);
+const char*	xmlGetCharEncodingName	(xmlCharEncoding enc);
 xmlCharEncodingHandlerPtr xmlGetCharEncodingHandler(xmlCharEncoding enc);
 xmlCharEncodingHandlerPtr xmlFindCharEncodingHandler(const char *name);
 int	xmlCheckUTF8			(const unsigned char *utf);
@@ -147,6 +150,9 @@
 int	xmlCharEncInFunc		(xmlCharEncodingHandler *handler,
 					 xmlBufferPtr out,
 					 xmlBufferPtr in);
+int	xmlCharEncFirstLine		(xmlCharEncodingHandler *handler,
+					 xmlBufferPtr out,
+					 xmlBufferPtr in);
 int	xmlCharEncCloseFunc		(xmlCharEncodingHandler *handler);
 
 #ifdef __cplusplus
diff --git a/include/libxml/entities.h b/include/libxml/entities.h
index f0ec731..c9bd003 100644
--- a/include/libxml/entities.h
+++ b/include/libxml/entities.h
@@ -106,6 +106,8 @@
 						 const xmlChar *input);
 xmlChar *		xmlEncodeEntitiesReentrant(xmlDocPtr doc,
 						 const xmlChar *input);
+xmlChar *		xmlEncodeSpecialChars	(xmlDocPtr doc,
+						 const xmlChar *input);
 xmlEntitiesTablePtr	xmlCreateEntitiesTable	(void);
 xmlEntitiesTablePtr	xmlCopyEntitiesTable	(xmlEntitiesTablePtr table);
 void			xmlFreeEntitiesTable	(xmlEntitiesTablePtr table);
diff --git a/include/libxml/parser.h b/include/libxml/parser.h
index aa7e273..9cb73bd 100644
--- a/include/libxml/parser.h
+++ b/include/libxml/parser.h
@@ -120,8 +120,8 @@
     xmlDocPtr           myDoc;        /* the document being built */
     int            wellFormed;        /* is the document well formed */
     int       replaceEntities;        /* shall we replace entities ? */
-    const xmlChar       *version;        /* the XML version string */
-    const xmlChar      *encoding;        /* encoding, if any */
+    const xmlChar    *version;        /* the XML version string */
+    const xmlChar   *encoding;        /* the declared encoding, if any */
     int            standalone;        /* standalone document */
     int                  html;        /* are we parsing an HTML document */
 
@@ -177,7 +177,11 @@
     int *              spaceTab;      /* array of space infos */
 
     int                depth;         /* to prevent entity substitution loops */
-    xmlParserInputPtr  entity;      /* used to check entities boundaries */
+    xmlParserInputPtr  entity;        /* used to check entities boundaries */
+    int                charset;       /* encoding of the in-memory content
+				         actually an xmlCharEncoding */
+    int                nodelen;       /* Those two fields are there to */
+    int                nodemem;       /* Speed up large node parsing */
 };
 
 /**
diff --git a/include/libxml/tree.h b/include/libxml/tree.h
index 35ea525..9c5b280 100644
--- a/include/libxml/tree.h
+++ b/include/libxml/tree.h
@@ -181,6 +181,7 @@
     xmlElementTypeVal      etype;	/* The type */
     xmlElementContentPtr content;	/* the allowed element content */
     xmlAttributePtr   attributes;	/* List of the declared attributes */
+    const xmlChar        *prefix;	/* the namespace prefix if any */
 };
 
 /*
@@ -347,13 +348,23 @@
     struct _xmlDtd  *extSubset;	/* the document external subset */
     struct _xmlNs   *oldNs;	/* Global namespace, the old way */
     const xmlChar  *version;	/* the XML version string */
-    const xmlChar  *encoding;   /* encoding, if any */
+    const xmlChar  *encoding;   /* external initial encoding, if any */
     void           *ids;        /* Hash table for ID attributes if any */
     void           *refs;       /* Hash table for IDREFs attributes if any */
     const xmlChar  *URL;	/* The URI for that document */
+    int             charset;    /* encoding of the in-memory content
+				   actually an xmlCharEncoding */
 };
 
 /*
+ * Compatibility naming layer with libxml1
+ */
+#ifndef xmlChildrenNode
+#define xmlChildrenNode children
+#define xmlRootNode children
+#endif
+
+/*
  * Variables.
  */
 extern xmlNsPtr baseDTD;
@@ -374,6 +385,9 @@
 void		xmlBufferAdd		(xmlBufferPtr buf,
 					 const xmlChar *str,
 					 int len);
+void		xmlBufferAddHead	(xmlBufferPtr buf,
+					 const xmlChar *str,
+					 int len);
 void		xmlBufferCat		(xmlBufferPtr buf,
 					 const xmlChar *str);
 void		xmlBufferCCat		(xmlBufferPtr buf,
@@ -545,6 +559,9 @@
 xmlChar *	xmlNodeListGetString	(xmlDocPtr doc,
 					 xmlNodePtr list,
 					 int inLine);
+xmlChar *	xmlNodeListGetRawString	(xmlDocPtr doc,
+					 xmlNodePtr list,
+					 int inLine);
 void		xmlNodeSetContent	(xmlNodePtr cur,
 					 const xmlChar *content);
 void		xmlNodeSetContentLen	(xmlNodePtr cur,
@@ -591,7 +608,7 @@
 void		xmlDocDumpMemory	(xmlDocPtr cur,
 					 xmlChar**mem,
 					 int *size);
-void		xmlDocDump		(FILE *f,
+int		xmlDocDump		(FILE *f,
 					 xmlDocPtr cur);
 void		xmlElemDump		(FILE *f,
 					 xmlDocPtr doc,
@@ -599,6 +616,17 @@
 int		xmlSaveFile		(const char *filename,
 					 xmlDocPtr cur);
 
+/* This one is exported from xmlIO.h
+ 
+int		xmlSaveFileTo		(xmlOutputBuffer *buf,
+					 xmlDocPtr cur,
+					 const char *encoding);
+ */ 					 
+
+int		xmlSaveFileEnc		(const char *filename,
+					 xmlDocPtr cur,
+					 const char *encoding);
+
 /*
  * Compression
  */
diff --git a/include/libxml/uri.h b/include/libxml/uri.h
index 59c4467..705e385 100644
--- a/include/libxml/uri.h
+++ b/include/libxml/uri.h
@@ -43,6 +43,8 @@
 xmlChar *	xmlBuildURI		(const xmlChar *URI,
 	                        	 const xmlChar *base);
 xmlURIPtr	xmlParseURI		(const char *URI);
+int		xmlParseURIReference	(xmlURIPtr uri,
+					 const char *str);
 xmlChar *	xmlSaveUri		(xmlURIPtr uri);
 void		xmlPrintURI		(FILE *stream,
 					 xmlURIPtr uri);
diff --git a/include/libxml/xmlIO.h b/include/libxml/xmlIO.h
index 2d14ebe..5289367 100644
--- a/include/libxml/xmlIO.h
+++ b/include/libxml/xmlIO.h
@@ -18,6 +18,11 @@
 extern "C" {
 #endif
 
+/*
+ * Those are the functions and datatypes for the parser input
+ * I/O structures.
+ */
+
 typedef int (*xmlInputMatchCallback) (char const *filename);
 typedef void * (*xmlInputOpenCallback) (char const *filename);
 typedef int (*xmlInputReadCallback) (void * context, char * buffer, int len);
@@ -32,13 +37,38 @@
     
     xmlCharEncodingHandlerPtr encoder; /* I18N conversions to UTF-8 */
     
-    xmlBufferPtr buffer;    /* Local buffer encoded in  UTF-8 */
+    xmlBufferPtr buffer;    /* Local buffer encoded in UTF-8 or ISOLatin */
     xmlBufferPtr raw;       /* if encoder != NULL buffer for raw input */
 };
 
 
 /*
- * Interfaces
+ * Those are the functions and datatypes for the library output
+ * I/O structures.
+ */
+
+typedef int (*xmlOutputMatchCallback) (char const *filename);
+typedef void * (*xmlOutputOpenCallback) (char const *filename);
+typedef int (*xmlOutputWriteCallback) (void * context, const char * buffer,
+                                       int len);
+typedef void (*xmlOutputCloseCallback) (void * context);
+
+typedef struct _xmlOutputBuffer xmlOutputBuffer;
+typedef xmlOutputBuffer *xmlOutputBufferPtr;
+struct _xmlOutputBuffer {
+    void*                   context;
+    xmlOutputWriteCallback  writecallback;
+    xmlOutputCloseCallback  closecallback;
+    
+    xmlCharEncodingHandlerPtr encoder; /* I18N conversions to UTF-8 */
+    
+    xmlBufferPtr buffer;    /* Local buffer encoded in UTF-8 or ISOLatin */
+    xmlBufferPtr conv;      /* if encoder != NULL buffer for output */
+    int written;            /* total number of byte written */
+};
+
+/*
+ * Interfaces for input
  */
 
 xmlParserInputBufferPtr
@@ -72,6 +102,51 @@
 						 xmlInputOpenCallback open,
 						 xmlInputReadCallback read,
 						 xmlInputCloseCallback close);
+/*
+ * Interfaces for output
+ */
+xmlOutputBufferPtr
+	xmlAllocOutputBuffer		(xmlCharEncodingHandlerPtr encoder);
+
+xmlOutputBufferPtr
+	xmlOutputBufferCreateFilename	(const char *URI,
+					 xmlCharEncodingHandlerPtr encoder,
+					 int compression);
+
+xmlOutputBufferPtr
+	xmlOutputBufferCreateFile	(FILE *file,
+					 xmlCharEncodingHandlerPtr encoder);
+
+xmlOutputBufferPtr
+	xmlOutputBufferCreateFd		(int fd,
+					 xmlCharEncodingHandlerPtr encoder);
+
+xmlOutputBufferPtr
+	xmlOutputBufferCreateIO		(xmlOutputWriteCallback   iowrite,
+					 xmlOutputCloseCallback  ioclose,
+					 void *ioctx,
+					 xmlCharEncodingHandlerPtr encoder);
+
+int	xmlOutputBufferWrite		(xmlOutputBufferPtr out,
+					 int len,
+					 const char *buf);
+int	xmlOutputBufferWriteString	(xmlOutputBufferPtr out,
+					 const char *str);
+
+int	xmlOutputBufferFlush		(xmlOutputBufferPtr out);
+int	xmlOutputBufferClose		(xmlOutputBufferPtr out);
+
+int     xmlRegisterOutputCallbacks	(xmlOutputMatchCallback match,
+					 xmlOutputOpenCallback open,
+					 xmlOutputWriteCallback write,
+					 xmlOutputCloseCallback close);
+
+/*
+ * This save function is part of tree.h actually
+ */
+int		xmlSaveFileTo		(xmlOutputBuffer *buf,
+					 xmlDocPtr cur,
+					 const char *encoding);
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/libxml/xmlversion.h.in b/include/libxml/xmlversion.h.in
index 5a62c27..b5edc09 100644
--- a/include/libxml/xmlversion.h.in
+++ b/include/libxml/xmlversion.h.in
@@ -9,8 +9,14 @@
 #ifndef __XML_VERSION_H__
 #define __XML_VERSION_H__
 
+/*
+ * use those to be sure nothing nasty will happen if
+ * your library and includes mismatch
+ */
+extern void xmlCheckVersion(int version);
 #define LIBXML_VERSION @LIBXML_VERSION_NUMBER@
 #define LIBXML_VERSION_STRING "@LIBXML_VERSION_NUMBER@"
+#define LIBXML_TEST_VERSION xmlCheckVersion(@LIBXML_VERSION_NUMBER@);
 
 /*
  * Whether the FTP support is configured in
diff --git a/include/libxml/xpath.h b/include/libxml/xpath.h
index 73e3f65..fc567fd 100644
--- a/include/libxml/xpath.h
+++ b/include/libxml/xpath.h
@@ -29,8 +29,8 @@
 typedef struct _xmlNodeSet xmlNodeSet;
 typedef xmlNodeSet *xmlNodeSetPtr;
 struct _xmlNodeSet {
-    int nodeNr;			/* # of node in the set */
-    int nodeMax;		/* allocated space */
+    int nodeNr;			/* number of nodes in the set */
+    int nodeMax;		/* size of the array as allocated */
     xmlNodePtr *nodeTab;	/* array of nodes in no particular order */
 };
 
@@ -41,6 +41,8 @@
  *   - boolean
  *   - number
  *   - string
+ *
+ * @@ XPointer will add more types !
  */
 
 #define XPATH_UNDEFINED	0
diff --git a/nanoftp.c b/nanoftp.c
index 6ca3701..9ebe015 100644
--- a/nanoftp.c
+++ b/nanoftp.c
@@ -1193,7 +1193,9 @@
 	if (sscanf(cur, "%d,%d,%d,%d,%d,%d", &temp[0], &temp[1], &temp[2],
 	            &temp[3], &temp[4], &temp[5]) != 6) {
 	    fprintf(stderr, "Invalid answer to PASV\n");
-	    close(ctxt->dataFd); ctxt->dataFd = -1;
+	    if (ctxt->dataFd != -1) {
+		close(ctxt->dataFd); ctxt->dataFd = -1;
+	    }
 	    return(-1);
 	}
 	for (i=0; i<6; i++) ad[i] = (unsigned char) (temp[i] & 0xff);
@@ -1448,6 +1450,8 @@
         if (xmlNanoFTPCwd(ctxt, ctxt->path) < 1)
 	    return(-1);
 	ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
+	if (ctxt->dataFd == -1)
+	    return(-1);
 #ifndef HAVE_SNPRINTF
 	len = sprintf(buf, "LIST -L\r\n");
 #else /* HAVE_SNPRINTF */
@@ -1459,6 +1463,8 @@
 		return(-1);
 	}
 	ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
+	if (ctxt->dataFd == -1)
+	    return(-1);
 #ifndef HAVE_SNPRINTF
 	len = sprintf(buf, "LIST -L %s\r\n", filename);
 #else /* HAVE_SNPRINTF */
@@ -1554,6 +1560,8 @@
     if ((filename == NULL) && (ctxt->path == NULL))
 	return(-1);
     ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
+    if (ctxt->dataFd == -1)
+	return(-1);
 
 #ifndef HAVE_SNPRINTF
     len = sprintf(buf, "TYPE I\r\n");
diff --git a/nanohttp.c b/nanohttp.c
index a94d6bb..33d0b7a 100644
--- a/nanohttp.c
+++ b/nanohttp.c
@@ -654,6 +654,23 @@
 	    close(s);
 	    return(-1);
     }
+
+    if ( FD_ISSET(s, &wfd) ) {
+	socklen_t len;
+	len = sizeof(status);
+	if (getsockopt(s, SOL_SOCKET, SO_ERROR, &status, &len) < 0 ) {
+	    /* Solaris error code */
+	    return (-1);
+	}
+	if ( status ) {
+	    close (s);
+	    errno = status;
+	    return (-1);
+	}
+    } else {
+	/* pbm */
+	return (-1);
+    }
     
     return(s);
 }
diff --git a/parser.c b/parser.c
index 6714d3c..6667106 100644
--- a/parser.c
+++ b/parser.c
@@ -47,7 +47,6 @@
 #define XML_PARSER_BIG_BUFFER_SIZE 1000
 #define XML_PARSER_BUFFER_SIZE 100
 
-const char *xmlParserVersion = LIBXML_VERSION_STRING;
 int xmlGetWarningsDefaultValue = 1;
 
 /*
@@ -63,6 +62,37 @@
 void xmlParserHandlePEReference(xmlParserCtxtPtr ctxt);
 xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
                                        const xmlChar **str);
+
+/*
+ * Version handling
+ */
+const char *xmlParserVersion = LIBXML_VERSION_STRING;
+
+/*
+ * xmlCheckVersion:
+ * @version: the include version number
+ *
+ * check the compiled lib version against the include one.
+ * This can warn or immediately kill the application
+ */
+void
+xmlCheckVersion(int version) {
+    int myversion = LIBXML_VERSION;
+
+    if ((myversion / 10000) != (version / 10000)) {
+	fprintf(stderr, 
+		"Fatal: program compiled against libxml %d using libxml %d\n",
+		(version / 10000), (myversion / 10000));
+	exit(1);
+    }
+    if ((myversion / 100) < (version / 100)) {
+	fprintf(stderr, 
+		"Warning: program compiled against libxml %d using older %d\n",
+		(version / 100), (myversion / 100));
+    }
+}
+
+
 /************************************************************************
  *									*
  * 		Input handling functions for progressive parsing	*
@@ -431,7 +461,7 @@
 	    if (*(ctxt->input->cur) == '\n') {
 		ctxt->input->line++; ctxt->input->col = 1;
 	    } else ctxt->input->col++;
-	    if (ctxt->encoding == NULL) {
+	    if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
 		/*
 		 * We are supposed to handle UTF8, check it's valid
 		 * From rfc2044: encoding of the Unicode values on UTF-8:
@@ -522,12 +552,16 @@
      * to ISO-Latin-1 (if you don't like this policy, just declare the
      * encoding !)
      */
-    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
+    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
 	ctxt->sax->error(ctxt->userData, 
 			 "Input is not proper UTF-8, indicate encoding !\n");
+	ctxt->sax->error(ctxt->userData, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
+			ctxt->input->cur[0], ctxt->input->cur[1],
+			ctxt->input->cur[2], ctxt->input->cur[3]);
+    }
     ctxt->errNo = XML_ERR_INVALID_ENCODING;
 
-    ctxt->encoding = xmlStrdup(BAD_CAST "ISO-8859-1"); 
+    ctxt->charset = XML_CHAR_ENCODING_8859_1; 
     ctxt->input->cur++;
     return;
 }
@@ -556,7 +590,7 @@
 	*len = 0;
 	return(ctxt->token);
     }	
-    if (ctxt->encoding == NULL) {
+    if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
 	/*
 	 * We are supposed to handle UTF8, check it's valid
 	 * From rfc2044: encoding of the Unicode values on UTF-8:
@@ -654,12 +688,16 @@
      * to ISO-Latin-1 (if you don't like this policy, just declare the
      * encoding !)
      */
-    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
+    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
 	ctxt->sax->error(ctxt->userData, 
 			 "Input is not proper UTF-8, indicate encoding !\n");
+	ctxt->sax->error(ctxt->userData, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
+			ctxt->input->cur[0], ctxt->input->cur[1],
+			ctxt->input->cur[2], ctxt->input->cur[3]);
+    }
     ctxt->errNo = XML_ERR_INVALID_ENCODING;
 
-    ctxt->encoding = xmlStrdup(BAD_CAST "ISO-8859-1"); 
+    ctxt->charset = XML_CHAR_ENCODING_8859_1; 
     *len = 1;
     return((int) *ctxt->input->cur);
 }
@@ -678,7 +716,7 @@
 
 int
 xmlStringCurrentChar(xmlParserCtxtPtr ctxt, const xmlChar *cur, int *len) {
-    if (ctxt->encoding == NULL) {
+    if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
 	/*
 	 * We are supposed to handle UTF8, check it's valid
 	 * From rfc2044: encoding of the Unicode values on UTF-8:
@@ -755,9 +793,13 @@
      * to ISO-Latin-1 (if you don't like this policy, just declare the
      * encoding !)
      */
-    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
+    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
 	ctxt->sax->error(ctxt->userData, 
 			 "Input is not proper UTF-8, indicate encoding !\n");
+	ctxt->sax->error(ctxt->userData, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
+			ctxt->input->cur[0], ctxt->input->cur[1],
+			ctxt->input->cur[2], ctxt->input->cur[3]);
+    }
     ctxt->errNo = XML_ERR_INVALID_ENCODING;
 
     *len = 1;
@@ -1224,6 +1266,7 @@
     ctxt->inSubset = 0;
     ctxt->errNo = XML_ERR_OK;
     ctxt->depth = 0;
+    ctxt->charset = XML_CHAR_ENCODING_UTF8;
     xmlInitNodeInfoSeq(&ctxt->node_seq);
 }
 
@@ -1463,7 +1506,7 @@
 		ctxt->errNo = XML_ERR_INVALID_HEX_CHARREF;
 	        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
 		    ctxt->sax->error(ctxt->userData, 
-		         "xmlParseCharRef: invalid hexadecimal value\n");
+		         "xmlParseStringCharRef: invalid hexadecimal value\n");
 		ctxt->wellFormed = 0;
 		ctxt->disableSAX = 1;
 		val = 0;
@@ -1484,7 +1527,7 @@
 		ctxt->errNo = XML_ERR_INVALID_DEC_CHARREF;
 	        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
 		    ctxt->sax->error(ctxt->userData, 
-		         "xmlParseCharRef: invalid decimal value\n");
+		         "xmlParseStringCharRef: invalid decimal value\n");
 		ctxt->wellFormed = 0;
 		ctxt->disableSAX = 1;
 		val = 0;
@@ -2297,9 +2340,11 @@
 	    break;
 	case XML_CHAR_ENCODING_NONE:
 	    /* let's assume it's UTF-8 without the XML decl */
+	    ctxt->charset = XML_CHAR_ENCODING_UTF8;
 	    return(0);
 	case XML_CHAR_ENCODING_UTF8:
 	    /* default encoding, no conversion should be needed */
+	    ctxt->charset = XML_CHAR_ENCODING_UTF8;
 	    return(0);
 	default:
 	    break;
@@ -2316,12 +2361,15 @@
 		    ctxt->sax->error(ctxt->userData, "encoding unknown\n");
 		ctxt->wellFormed = 0;
 		ctxt->disableSAX = 1;
+		ctxt->charset = XML_CHAR_ENCODING_UTF8;
 		break;
 	    case XML_CHAR_ENCODING_NONE:
 		/* let's assume it's UTF-8 without the XML decl */
+		ctxt->charset = XML_CHAR_ENCODING_UTF8;
 		return(0);
 	    case XML_CHAR_ENCODING_UTF8:
 		/* default encoding, no conversion should be needed */
+		ctxt->charset = XML_CHAR_ENCODING_UTF8;
 		return(0);
 	    case XML_CHAR_ENCODING_UTF16LE:
 		break;
@@ -2380,6 +2428,7 @@
 		    (ctxt->input->encoding != NULL)) {
 		    ctxt->encoding = xmlStrdup(ctxt->input->encoding);
 		}
+		ctxt->charset = enc;
 		return(0);
 	    case XML_CHAR_ENCODING_2022_JP:
 		ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
@@ -2403,6 +2452,7 @@
     }
     if (handler == NULL)
 	return(-1);
+    ctxt->charset = XML_CHAR_ENCODING_UTF8;
     return(xmlSwitchToEncoding(ctxt, handler));
 }
 
@@ -2427,10 +2477,14 @@
 	        if (ctxt->input->buf->encoder != NULL) {
 		    if (ctxt->input->buf->encoder == handler)
 			return(0);
-		    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-			ctxt->sax->error(ctxt->userData,
-			     "xmlSwitchEncoding : encoder already regitered\n");
-		    return(-1);
+		    /*
+		     * Note: this is a bit dangerous, but that's what it
+		     * takes to use nearly compatible signature for different
+		     * encodings.
+		     */
+		    xmlCharEncCloseFunc(ctxt->input->buf->encoder);
+		    ctxt->input->buf->encoder = handler;
+		    return(0);
 		}
 		ctxt->input->buf->encoder = handler;
 
@@ -2468,12 +2522,14 @@
 		    ctxt->input->buf->buffer = xmlBufferCreate();
 
 		    /*
-		     * convert as much as possible of the raw input
-		     * to the parser reading buffer.
+		     * convert just enough to get
+		     * '<?xml version="1.0" encoding="xxx"?>'
+		     * parsed with the autodetected encoding
+		     * into the parser reading buffer.
 		     */
-		    nbchars = xmlCharEncInFunc(ctxt->input->buf->encoder,
-		                               ctxt->input->buf->buffer,
-					       ctxt->input->buf->raw);
+		    nbchars = xmlCharEncFirstLine(ctxt->input->buf->encoder,
+		                                  ctxt->input->buf->buffer,
+					          ctxt->input->buf->raw);
 		    if (nbchars < 0) {
 			fprintf(stderr, "xmlSwitchToEncoding: encoder error\n");
 			return(-1);
@@ -2536,10 +2592,7 @@
 	/*
 	 * The parsing is now done in UTF8 natively
 	 */
-	if (ctxt->encoding != NULL) {
-	    xmlFree((xmlChar *) ctxt->encoding);
-	    ctxt->encoding = NULL;
-	}
+	ctxt->charset = XML_CHAR_ENCODING_UTF8;
     } else 
 	return(-1);
     return(0);
@@ -3740,13 +3793,12 @@
 xmlChar *
 xmlParseAttValue(xmlParserCtxtPtr ctxt) {
     xmlChar limit = 0;
-    xmlChar *buffer = NULL;
-    int buffer_size = 0;
-    xmlChar *out = NULL;
-
+    xmlChar *buf = NULL;
+    int len = 0;
+    int buf_size = 0;
+    int c, l;
     xmlChar *current = NULL;
     xmlEntityPtr ent;
-    xmlChar cur;
 
 
     SHRINK;
@@ -3770,24 +3822,24 @@
     /*
      * allocate a translation buffer.
      */
-    buffer_size = XML_PARSER_BUFFER_SIZE;
-    buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
-    if (buffer == NULL) {
+    buf_size = XML_PARSER_BUFFER_SIZE;
+    buf = (xmlChar *) xmlMalloc(buf_size * sizeof(xmlChar));
+    if (buf == NULL) {
 	perror("xmlParseAttValue: malloc failed");
 	return(NULL);
     }
-    out = buffer;
 
     /*
      * Ok loop until we reach one of the ending char or a size limit.
      */
-    cur = CUR;
-    while (((NXT(0) != limit) && (cur != '<')) || (ctxt->token != 0)) {
-	if (cur == 0) break;
-        if ((cur == '&') && (NXT(1) == '#')) {
+    c = CUR_CHAR(l);
+    while (((NXT(0) != limit) && (c != '<')) || (ctxt->token != 0)) {
+	if (c == 0) break;
+        if ((c == '&') && (NXT(1) == '#')) {
 	    int val = xmlParseCharRef(ctxt);
-	    *out++ = val;
-	} else if (cur == '&') {
+	    COPY_BUF(l,buf,len,val);
+	    NEXTL(l);
+	} else if (c == '&') {
 	    ent = xmlParseEntityRef(ctxt);
 	    if ((ent != NULL) && 
 		(ctxt->replaceEntities != 0)) {
@@ -3799,19 +3851,16 @@
 		    if (rep != NULL) {
 			current = rep;
 			while (*current != 0) {
-			    *out++ = *current++;
-			    if (out - buffer > buffer_size - 10) {
-				int index = out - buffer;
-
-				growBuffer(buffer);
-				out = &buffer[index];
+			    buf[len++] = *current++;
+			    if (len > buf_size - 10) {
+				growBuffer(buf);
 			    }
 			}
 			xmlFree(rep);
 		    }
 		} else {
 		    if (ent->content != NULL)
-			*out++ = ent->content[0];
+			buf[len++] = ent->content[0];
 		}
 	    } else if (ent != NULL) {
 		int i = xmlStrlen(ent->name);
@@ -3832,41 +3881,32 @@
 		/*
 		 * Just output the reference
 		 */
-		*out++ = '&';
-		if (out - buffer > buffer_size - i - 10) {
-		    int index = out - buffer;
-
-		    growBuffer(buffer);
-		    out = &buffer[index];
+		buf[len++] = '&';
+		if (len > buf_size - i - 10) {
+		    growBuffer(buf);
 		}
 		for (;i > 0;i--)
-		    *out++ = *cur++;
-		*out++ = ';';
+		    buf[len++] = *cur++;
+		buf[len++] = ';';
 	    }
 	} else {
-	    /*  invalid for UTF-8 , use COPY(out); !!! */
-	    if ((cur == 0x20) || (cur == 0xD) || (cur == 0xA) || (cur == 0x9)) {
-		*out++ = 0x20;
-		if (out - buffer > buffer_size - 10) {
-		  int index = out - buffer;
-		  
-		  growBuffer(buffer);
-		  out = &buffer[index];
+	    if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
+		COPY_BUF(l,buf,len,0x20);
+		if (len > buf_size - 10) {
+		    growBuffer(buf);
 		}
 	    } else {
-		*out++ = cur;
-		if (out - buffer > buffer_size - 10) {
-		  int index = out - buffer;
-		  
-		  growBuffer(buffer);
-		  out = &buffer[index];
+		COPY_BUF(l,buf,len,c);
+		if (len > buf_size - 10) {
+		    growBuffer(buf);
 		}
 	    }
-	    NEXT;
+	    NEXTL(l);
 	}
-	cur = CUR;
+	GROW;
+	c = CUR_CHAR(l);
     }
-    *out++ = 0;
+    buf[len++] = 0;
     if (RAW == '<') {
 	if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
 	    ctxt->sax->error(ctxt->userData,
@@ -3882,7 +3922,7 @@
 	ctxt->disableSAX = 1;
     } else
 	NEXT;
-    return(buffer);
+    return(buf);
 }
 
 /**
@@ -6341,7 +6381,7 @@
 	int hex = NXT(2);
 	int val = xmlParseCharRef(ctxt);
 	
-	if (ctxt->encoding != NULL) {
+	if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
 	    /*
 	     * So we are using non-UTF-8 buffers
 	     * Check that the char fit on 8bits, if not
@@ -6507,7 +6547,7 @@
 			ctxt->instate = XML_PARSER_EOF;
 			return;
 		    }
-		    if (input->standalone) {
+		    if (input->standalone == 1) {
 			if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
 			    ctxt->sax->error(ctxt->userData,
 			    "external parsed entities cannot be standalone\n");
@@ -9558,15 +9598,6 @@
         xmlParseTryOrFinish(ctxt, terminate);
     if (terminate) {
 	/*
-	 * Grab the encoding if it was added on-the-fly
-	 */
-	if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) &&
-	    (ctxt->myDoc->encoding == NULL)) {
-	    ctxt->myDoc->encoding = ctxt->encoding;
-	    ctxt->encoding = NULL;
-	}
-
-	/*
 	 * Check for termination
 	 */
 	if ((ctxt->instate != XML_PARSER_EOF) &&
diff --git a/parser.h b/parser.h
index aa7e273..9cb73bd 100644
--- a/parser.h
+++ b/parser.h
@@ -120,8 +120,8 @@
     xmlDocPtr           myDoc;        /* the document being built */
     int            wellFormed;        /* is the document well formed */
     int       replaceEntities;        /* shall we replace entities ? */
-    const xmlChar       *version;        /* the XML version string */
-    const xmlChar      *encoding;        /* encoding, if any */
+    const xmlChar    *version;        /* the XML version string */
+    const xmlChar   *encoding;        /* the declared encoding, if any */
     int            standalone;        /* standalone document */
     int                  html;        /* are we parsing an HTML document */
 
@@ -177,7 +177,11 @@
     int *              spaceTab;      /* array of space infos */
 
     int                depth;         /* to prevent entity substitution loops */
-    xmlParserInputPtr  entity;      /* used to check entities boundaries */
+    xmlParserInputPtr  entity;        /* used to check entities boundaries */
+    int                charset;       /* encoding of the in-memory content
+				         actually an xmlCharEncoding */
+    int                nodelen;       /* Those two fields are there to */
+    int                nodemem;       /* Speed up large node parsing */
 };
 
 /**
diff --git a/result/HTML/test3.html b/result/HTML/test3.html
index ad97957..597a1a4 100644
--- a/result/HTML/test3.html
+++ b/result/HTML/test3.html
@@ -1,6 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
 <html>
 <head><base target="contents"></head>
+<body>
 <a name="ProblemDomain.Package"><h2>Component Package diagram ProblemDomain</h2></a>
 <p>
 <hr>
@@ -53,4 +54,5 @@
 <a href="DataManagement.Package.html#DataManagement.Package">DataManagement</a>
 </li></ul>
 <dir></dir>
+</body>
 </html>
diff --git a/result/HTML/wired.html b/result/HTML/wired.html
index 509bc1b..d4439bb 100644
--- a/result/HTML/wired.html
+++ b/result/HTML/wired.html
@@ -9,7 +9,7 @@
 <td ROWSPAN="2" ALIGN="LEFT" BGCOLOR="FFFFFF"><input TYPE="IMAGE" SRC="http://static.wired.com/advertising/blipverts/allapartments/990625jpa_ssthome.gif" WIDTH="375" HEIGHT="60" BORDER="0" VALUE="search" HSPACE="0" alt="Search over 6,000,000 Apts with SpringStreet"></td>
 </tr>
 <tr><td BGCOLOR="#330099">
-<select NAME="state"><option VALUE="WA">WA

+<select NAME="state"><option VALUE="WA" SELECTED>WA

 <option VALUE="AL">AL</option>
 <option VALUE="AK">AK</option>
 <option VALUE="AZ">AZ</option>
@@ -89,7 +89,7 @@
 <td colspan="2" bgcolor="#999999"><table border="0" cellspacing="0" cellpadding="5"><form name="RedirectSearch" action="http://redirect.wired.com/search"><tr>
 <td><font face="courier" size="1"><input type="TEXT" name="query" size="20" value=""></font></td>
 <td><select name="url">
-<option value="http://search.hotwired.com/search97/s97.vts?Action=FilterSearch&amp;Filter=docs_filter.hts&amp;ResultTemplate=vignette.hts&amp;Collection=vignette&amp;QueryMode=Internet&amp;Query=">Wired News</option>
+<option value="http://search.hotwired.com/search97/s97.vts?Action=FilterSearch&amp;Filter=docs_filter.hts&amp;ResultTemplate=vignette.hts&amp;Collection=vignette&amp;QueryMode=Internet&amp;Query=" selected>Wired News</option>
 <option value="http://search.hotwired.com/search97/s97.vts?Action=FilterSearch&amp;Filter=docs_filter.hts&amp;ResultTemplate=webmonkey.hts&amp;Collection=webmonkey&amp;QueryMode=Internet&amp;Query=">Webmonkey</option>
 <option value="http://search.hotwired.com/search97/s97.vts?collection=webmonkey_guides&amp;Action=FilterSearch&amp;filter=docs_filter.hts&amp;ResultTemplate=webmonkey_guides.hts&amp;QueryMode=Internet&amp;Query=">Webmonkey Guides</option>
 <option value="http://search.hotwired.com/search97/s97.vts?collection=hotwired&amp;Action=FilterSearch&amp;filter=docs_filter.hts&amp;ResultTemplate=hotwired_archive.hts&amp;QueryMode=Internet&amp;Query=">HotWired Archives</option>
diff --git a/testURI.c b/testURI.c
index 6712119..0cb904c 100644
--- a/testURI.c
+++ b/testURI.c
@@ -17,6 +17,8 @@
 #include <stdio.h>
 #include <stdarg.h>
 
+#include <libxml/xmlversion.h>
+#include <libxml/xmlmemory.h>
 #include <libxml/uri.h>
 
 int main(int argc, char **argv) {
diff --git a/tree.c b/tree.c
index 74b5321..b81b7a6 100644
--- a/tree.c
+++ b/tree.c
@@ -847,6 +847,80 @@
 }
 
 /**
+ * xmlNodeListGetRawString:
+ * @doc:  the document
+ * @list:  a Node list
+ * @inLine:  should we replace entity contents or show their external form
+ *
+ * Returns the string equivalent to the text contained in the Node list
+ * made of TEXTs and ENTITY_REFs, contrary to xmlNodeListGetString()
+ * this function doesn't do any character encoding handling.
+ *
+ * Returns a pointer to the string copy, the calller must free it.
+ */
+xmlChar *
+xmlNodeListGetRawString(xmlDocPtr doc, xmlNodePtr list, int inLine) {
+    xmlNodePtr node = list;
+    xmlChar *ret = NULL;
+    xmlEntityPtr ent;
+
+    if (list == NULL) return(NULL);
+
+    while (node != NULL) {
+        if (node->type == XML_TEXT_NODE) {
+	    if (inLine) {
+#ifndef XML_USE_BUFFER_CONTENT
+		ret = xmlStrcat(ret, node->content);
+#else
+		ret = xmlStrcat(ret, xmlBufferContent(node->content));
+#endif
+	    } else {
+	        xmlChar *buffer;
+
+#ifndef XML_USE_BUFFER_CONTENT
+		buffer = xmlEncodeSpecialChars(doc, node->content);
+#else
+		buffer = xmlEncodeSpecialChars(doc,
+					    xmlBufferContent(node->content));
+#endif
+		if (buffer != NULL) {
+		    ret = xmlStrcat(ret, buffer);
+		    xmlFree(buffer);
+		}
+            }
+	} else if (node->type == XML_ENTITY_REF_NODE) {
+	    if (inLine) {
+		ent = xmlGetDocEntity(doc, node->name);
+		if (ent != NULL)
+		    ret = xmlStrcat(ret, ent->content);
+		else {
+#ifndef XML_USE_BUFFER_CONTENT
+		    ret = xmlStrcat(ret, node->content);
+#else
+		    ret = xmlStrcat(ret, xmlBufferContent(node->content));
+#endif
+		}    
+            } else {
+	        xmlChar buf[2];
+		buf[0] = '&'; buf[1] = 0;
+		ret = xmlStrncat(ret, buf, 1);
+		ret = xmlStrcat(ret, node->name);
+		buf[0] = ';'; buf[1] = 0;
+		ret = xmlStrncat(ret, buf, 1);
+	    }
+	}
+#if 0
+	else {
+	    fprintf(stderr, "xmlGetNodeListString : invalide node type %d\n",
+	            node->type);
+	}
+#endif
+	node = node->next;
+    }
+    return(ret);
+}
+
+/**
  * xmlNewProp:
  * @node:  the holding node
  * @name:  the name of the attribute
@@ -3787,7 +3861,7 @@
 
     if (len <= buf->use) return(0);
 
-    size = buf->size + buf->use + len + 100;
+    size = buf->use + len + 100;
 
     newbuf = xmlRealloc(buf->content, size);
     if (newbuf == NULL) return(-1);
@@ -3949,6 +4023,52 @@
 }
 
 /**
+ * xmlBufferAddHead:
+ * @buf:  the buffer
+ * @str:  the xmlChar string
+ * @len:  the number of xmlChar to add
+ *
+ * Add a string range to the beginning of an XML buffer.
+ * if len == -1, the lenght of @str is recomputed.
+ */
+void
+xmlBufferAddHead(xmlBufferPtr buf, const xmlChar *str, int len) {
+    int needSize;
+
+    if (str == NULL) {
+#ifdef DEBUG_BUFFER
+        fprintf(stderr, "xmlBufferAdd: str == NULL\n");
+#endif
+	return;
+    }
+    if (len < -1) {
+#ifdef DEBUG_BUFFER
+        fprintf(stderr, "xmlBufferAdd: len < 0\n");
+#endif
+	return;
+    }
+    if (len == 0) return;
+
+    if (len < 0)
+        len = xmlStrlen(str);
+
+    if (len <= 0) return;
+
+    needSize = buf->use + len + 2;
+    if(needSize > buf->size){
+        if(!xmlBufferResize(buf, needSize)){
+            fprintf(stderr, "xmlBufferAddHead : out of memory!\n");
+            return;
+        }
+    }
+
+    memmove(&buf->content[len], &buf->content[0], buf->use * sizeof(xmlChar));
+    memmove(&buf->content[0], str, len * sizeof(xmlChar));
+    buf->use += len;
+    buf->content[buf->use] = 0;
+}
+
+/**
  * xmlBufferCat:
  * @buf:  the buffer to dump
  * @str:  the xmlChar string
@@ -4045,6 +4165,12 @@
 }
 
 
+/************************************************************************
+ *									*
+ *   		Dumping XML tree content to a simple buffer		*
+ *									*
+ ************************************************************************/
+
 static void
 xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
             int format);
@@ -4528,6 +4654,489 @@
     }
 }
 
+/************************************************************************
+ *									*
+ *   		Dumping XML tree content to an I/O output buffer	*
+ *									*
+ ************************************************************************/
+
+static void
+xmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
+                  int level, int format, const char *encoding);
+static void
+xmlNodeListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
+                  int level, int format, const char *encoding);
+/**
+ * xmlGlobalNsDumpOutput:
+ * @buf:  the XML buffer output
+ * @cur:  a namespace
+ *
+ * Dump a global Namespace, this is the old version based on PIs.
+ */
+static void
+xmlGlobalNsDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        fprintf(stderr, "xmlGlobalNsDump : Ns == NULL\n");
+#endif
+	return;
+    }
+    if (cur->type == XML_GLOBAL_NAMESPACE) {
+	xmlOutputBufferWriteString(buf, "<?namespace");
+	if (cur->href != NULL) {
+	    xmlOutputBufferWriteString(buf, " href=");
+	    xmlBufferWriteQuotedString(buf->buffer, cur->href);
+	}
+	if (cur->prefix != NULL) {
+	    xmlOutputBufferWriteString(buf, " AS=");
+	    xmlBufferWriteQuotedString(buf->buffer, cur->prefix);
+	}
+	xmlOutputBufferWriteString(buf, "?>\n");
+    }
+}
+
+/**
+ * xmlGlobalNsListDumpOutput:
+ * @buf:  the XML buffer output
+ * @cur:  the first namespace
+ *
+ * Dump a list of global Namespace, this is the old version based on PIs.
+ */
+static void
+xmlGlobalNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
+    while (cur != NULL) {
+        xmlGlobalNsDumpOutput(buf, cur);
+	cur = cur->next;
+    }
+}
+
+/**
+ * xmlNsDumpOutput:
+ * @buf:  the XML buffer output
+ * @cur:  a namespace
+ *
+ * Dump a local Namespace definition.
+ * Should be called in the context of attributes dumps.
+ */
+static void
+xmlNsDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        fprintf(stderr, "xmlNsDump : Ns == NULL\n");
+#endif
+	return;
+    }
+    if (cur->type == XML_LOCAL_NAMESPACE) {
+        /* Within the context of an element attributes */
+	if (cur->prefix != NULL) {
+	    xmlOutputBufferWriteString(buf, " xmlns:");
+	    xmlOutputBufferWriteString(buf, (const char *)cur->prefix);
+	} else
+	    xmlOutputBufferWriteString(buf, " xmlns");
+	xmlOutputBufferWriteString(buf, "=");
+	xmlBufferWriteQuotedString(buf->buffer, cur->href);
+    }
+}
+
+/**
+ * xmlNsListDumpOutput:
+ * @buf:  the XML buffer output
+ * @cur:  the first namespace
+ *
+ * Dump a list of local Namespace definitions.
+ * Should be called in the context of attributes dumps.
+ */
+static void
+xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
+    while (cur != NULL) {
+        xmlNsDumpOutput(buf, cur);
+	cur = cur->next;
+    }
+}
+
+/**
+ * xmlDtdDumpOutput:
+ * @buf:  the XML buffer output
+ * @doc:  the document
+ * @encoding:  an optional encoding string
+ * 
+ * Dump the XML document DTD, if any.
+ */
+static void
+xmlDtdDumpOutput(xmlOutputBufferPtr buf, xmlDtdPtr dtd, const char *encoding) {
+    if (dtd == NULL) {
+#ifdef DEBUG_TREE
+        fprintf(stderr, "xmlDtdDump : no internal subset\n");
+#endif
+	return;
+    }
+    xmlOutputBufferWriteString(buf, "<!DOCTYPE ");
+    xmlOutputBufferWriteString(buf, (const char *)dtd->name);
+    if (dtd->ExternalID != NULL) {
+	xmlOutputBufferWriteString(buf, " PUBLIC ");
+	xmlBufferWriteQuotedString(buf->buffer, dtd->ExternalID);
+	xmlOutputBufferWriteString(buf, " ");
+	xmlBufferWriteQuotedString(buf->buffer, dtd->SystemID);
+    }  else if (dtd->SystemID != NULL) {
+	xmlOutputBufferWriteString(buf, " SYSTEM ");
+	xmlBufferWriteQuotedString(buf->buffer, dtd->SystemID);
+    }
+    if ((dtd->entities == NULL) && (dtd->elements == NULL) &&
+        (dtd->attributes == NULL) && (dtd->notations == NULL)) {
+	xmlOutputBufferWriteString(buf, ">");
+	return;
+    }
+    xmlOutputBufferWriteString(buf, " [\n");
+    xmlNodeListDumpOutput(buf, dtd->doc, dtd->children, -1, 0, encoding);
+#if 0
+    if (dtd->entities != NULL)
+	xmlDumpEntitiesTable(buf, (xmlEntitiesTablePtr) dtd->entities);
+    if (dtd->notations != NULL)
+	xmlDumpNotationTable(buf, (xmlNotationTablePtr) dtd->notations);
+    if (dtd->elements != NULL)
+	xmlDumpElementTable(buf, (xmlElementTablePtr) dtd->elements);
+    if (dtd->attributes != NULL)
+	xmlDumpAttributeTable(buf, (xmlAttributeTablePtr) dtd->attributes);
+#endif
+    xmlOutputBufferWriteString(buf, "]>");
+}
+
+/**
+ * xmlAttrDumpOutput:
+ * @buf:  the XML buffer output
+ * @doc:  the document
+ * @cur:  the attribute pointer
+ * @encoding:  an optional encoding string
+ *
+ * Dump an XML attribute
+ */
+static void
+xmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur,
+	          const char *encoding) {
+    xmlChar *value;
+
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        fprintf(stderr, "xmlAttrDump : property == NULL\n");
+#endif
+	return;
+    }
+    xmlOutputBufferWriteString(buf, " ");
+    if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+        xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
+	xmlOutputBufferWriteString(buf, ":");
+    }
+    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+    value = xmlNodeListGetString(doc, cur->children, 0);
+    if (value) {
+	xmlOutputBufferWriteString(buf, "=");
+	xmlBufferWriteQuotedString(buf->buffer, value);
+	xmlFree(value);
+    } else  {
+	xmlOutputBufferWriteString(buf, "=\"\"");
+    }
+}
+
+/**
+ * xmlAttrListDumpOutput:
+ * @buf:  the XML buffer output
+ * @doc:  the document
+ * @cur:  the first attribute pointer
+ * @encoding:  an optional encoding string
+ *
+ * Dump a list of XML attributes
+ */
+static void
+xmlAttrListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
+	              xmlAttrPtr cur, const char *encoding) {
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        fprintf(stderr, "xmlAttrListDump : property == NULL\n");
+#endif
+	return;
+    }
+    while (cur != NULL) {
+        xmlAttrDumpOutput(buf, doc, cur, encoding);
+	cur = cur->next;
+    }
+}
+
+
+
+/**
+ * xmlNodeListDumpOutput:
+ * @buf:  the XML buffer output
+ * @doc:  the document
+ * @cur:  the first node
+ * @level: the imbrication level for indenting
+ * @format: is formatting allowed
+ * @encoding:  an optional encoding string
+ *
+ * Dump an XML node list, recursive behaviour,children are printed too.
+ */
+static void
+xmlNodeListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
+                xmlNodePtr cur, int level, int format, const char *encoding) {
+    int i;
+
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        fprintf(stderr, "xmlNodeListDump : node == NULL\n");
+#endif
+	return;
+    }
+    while (cur != NULL) {
+	if ((format) && (xmlIndentTreeOutput) &&
+	    (cur->type == XML_ELEMENT_NODE))
+	    for (i = 0;i < level;i++)
+		xmlOutputBufferWriteString(buf, "  ");
+        xmlNodeDumpOutput(buf, doc, cur, level, format, encoding);
+	if (format) {
+	    xmlOutputBufferWriteString(buf, "\n");
+	}
+	cur = cur->next;
+    }
+}
+
+/**
+ * xmlNodeDumpOutput:
+ * @buf:  the XML buffer output
+ * @doc:  the document
+ * @cur:  the current node
+ * @level: the imbrication level for indenting
+ * @format: is formatting allowed
+ * @encoding:  an optional encoding string
+ *
+ * Dump an XML node, recursive behaviour,children are printed too.
+ */
+static void
+xmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
+            int level, int format, const char *encoding) {
+    int i;
+    xmlNodePtr tmp;
+
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        fprintf(stderr, "xmlNodeDump : node == NULL\n");
+#endif
+	return;
+    }
+    if (cur->type == XML_DTD_NODE) {
+        xmlDtdDumpOutput(buf, (xmlDtdPtr) cur, encoding);
+	return;
+    }
+    if (cur->type == XML_ELEMENT_DECL) {
+        xmlDumpElementDecl(buf->buffer, (xmlElementPtr) cur);
+	return;
+    }
+    if (cur->type == XML_ATTRIBUTE_DECL) {
+        xmlDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur);
+	return;
+    }
+    if (cur->type == XML_ENTITY_DECL) {
+        xmlDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur);
+	return;
+    }
+    if (cur->type == XML_TEXT_NODE) {
+	if (cur->content != NULL) {
+            xmlChar *buffer;
+
+#ifndef XML_USE_BUFFER_CONTENT
+	    if (encoding == NULL)
+		buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
+	    else
+		buffer = xmlEncodeSpecialChars(doc, cur->content);
+#else
+	    if (encoding == NULL)
+		buffer = xmlEncodeEntitiesReentrant(doc, 
+				    xmlBufferContent(cur->content));
+	    else
+		buffer = xmlEncodeSpecialChars(doc, 
+				    xmlBufferContent(cur->content));
+#endif
+	    if (buffer != NULL) {
+		xmlOutputBufferWriteString(buf, (const char *)buffer);
+		xmlFree(buffer);
+	    }
+	}
+	return;
+    }
+    if (cur->type == XML_PI_NODE) {
+	if (cur->content != NULL) {
+	    xmlOutputBufferWriteString(buf, "<?");
+	    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+	    if (cur->content != NULL) {
+		xmlOutputBufferWriteString(buf, " ");
+#ifndef XML_USE_BUFFER_CONTENT
+		xmlOutputBufferWriteString(buf, (const char *)cur->content);
+#else
+		xmlOutputBufferWriteString(buf, (const char *)xmlBufferContent(cur->content));
+#endif
+	    }
+	    xmlOutputBufferWriteString(buf, "?>");
+	} else {
+	    xmlOutputBufferWriteString(buf, "<?");
+	    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+	    xmlOutputBufferWriteString(buf, "?>");
+	}
+	return;
+    }
+    if (cur->type == XML_COMMENT_NODE) {
+	if (cur->content != NULL) {
+	    xmlOutputBufferWriteString(buf, "<!--");
+#ifndef XML_USE_BUFFER_CONTENT
+	    xmlOutputBufferWriteString(buf, (const char *)cur->content);
+#else
+	    xmlOutputBufferWriteString(buf, (const char *)xmlBufferContent(cur->content));
+#endif
+	    xmlOutputBufferWriteString(buf, "-->");
+	}
+	return;
+    }
+    if (cur->type == XML_ENTITY_REF_NODE) {
+        xmlOutputBufferWriteString(buf, "&");
+	xmlOutputBufferWriteString(buf, (const char *)cur->name);
+        xmlOutputBufferWriteString(buf, ";");
+	return;
+    }
+    if (cur->type == XML_CDATA_SECTION_NODE) {
+        xmlOutputBufferWriteString(buf, "<![CDATA[");
+	if (cur->content != NULL)
+#ifndef XML_USE_BUFFER_CONTENT
+	    xmlOutputBufferWriteString(buf, (const char *)cur->content);
+#else
+	    xmlOutputBufferWriteString(buf, (const char *)xmlBufferContent(cur->content));
+#endif
+        xmlOutputBufferWriteString(buf, "]]>");
+	return;
+    }
+
+    if (format == 1) {
+	tmp = cur->children;
+	while (tmp != NULL) {
+	    if ((tmp->type == XML_TEXT_NODE) || 
+		(tmp->type == XML_ENTITY_REF_NODE)) {
+		format = 0;
+		break;
+	    }
+	    tmp = tmp->next;
+	}
+    }
+    xmlOutputBufferWriteString(buf, "<");
+    if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+        xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
+	xmlOutputBufferWriteString(buf, ":");
+    }
+
+    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+    if (cur->nsDef)
+        xmlNsListDumpOutput(buf, cur->nsDef);
+    if (cur->properties != NULL)
+        xmlAttrListDumpOutput(buf, doc, cur->properties, encoding);
+
+    if ((cur->content == NULL) && (cur->children == NULL) &&
+	(!xmlSaveNoEmptyTags)) {
+        xmlOutputBufferWriteString(buf, "/>");
+	return;
+    }
+    xmlOutputBufferWriteString(buf, ">");
+    if (cur->content != NULL) {
+	xmlChar *buffer;
+
+#ifndef XML_USE_BUFFER_CONTENT
+	if (encoding == NULL)
+	    buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
+	else
+	    buffer = xmlEncodeSpecialChars(doc, cur->content);
+#else
+	if (encoding == NULL)
+	    buffer = xmlEncodeEntitiesReentrant(doc, 
+				xmlBufferContent(cur->content));
+	else
+	    buffer = xmlEncodeSpecialChars(doc, 
+				xmlBufferContent(cur->content));
+#endif
+	if (buffer != NULL) {
+	    xmlOutputBufferWriteString(buf, (const char *)buffer);
+	    xmlFree(buffer);
+	}
+    }
+    if (cur->children != NULL) {
+	if (format) xmlOutputBufferWriteString(buf, "\n");
+	xmlNodeListDumpOutput(buf, doc, cur->children,
+		        (level >= 0?level+1:-1), format, encoding);
+	if ((xmlIndentTreeOutput) && (format))
+	    for (i = 0;i < level;i++)
+		xmlOutputBufferWriteString(buf, "  ");
+    }
+    xmlOutputBufferWriteString(buf, "</");
+    if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+        xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
+	xmlOutputBufferWriteString(buf, ":");
+    }
+
+    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+    xmlOutputBufferWriteString(buf, ">");
+}
+
+/**
+ * xmlDocContentDumpOutput:
+ * @buf:  the XML buffer output
+ * @cur:  the document
+ * @encoding:  an optional encoding string
+ *
+ * Dump an XML document.
+ */
+static void
+xmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
+	                const char *encoding) {
+    xmlOutputBufferWriteString(buf, "<?xml version=");
+    if (cur->version != NULL) 
+	xmlBufferWriteQuotedString(buf->buffer, cur->version);
+    else
+	xmlOutputBufferWriteString(buf, "\"1.0\"");
+    if (encoding == NULL) {
+	if (cur->encoding != NULL)
+	    encoding = (const char *) cur->encoding;
+	else if (cur->charset != XML_CHAR_ENCODING_UTF8)
+	    encoding = xmlGetCharEncodingName(cur->charset);
+    }
+    if (encoding != NULL) {
+        xmlOutputBufferWriteString(buf, " encoding=");
+	xmlBufferWriteQuotedString(buf->buffer, (xmlChar *) encoding);
+    }
+    switch (cur->standalone) {
+        case 0:
+	    xmlOutputBufferWriteString(buf, " standalone=\"no\"");
+	    break;
+        case 1:
+	    xmlOutputBufferWriteString(buf, " standalone=\"yes\"");
+	    break;
+    }
+    xmlOutputBufferWriteString(buf, "?>\n");
+    if (cur->children != NULL) {
+        xmlNodePtr child = cur->children;
+
+	/* global namespace definitions, the old way */
+	if (oldXMLWDcompatibility)
+	    xmlGlobalNsListDumpOutput(buf, cur->oldNs);
+	else 
+	    xmlUpgradeOldNs(cur);
+	
+	while (child != NULL) {
+	    xmlNodeDumpOutput(buf, cur, child, 0, 1, encoding);
+	    xmlOutputBufferWriteString(buf, "\n");
+	    child = child->next;
+	}
+    }
+}
+
+/************************************************************************
+ *									*
+ *		Saving functions front-ends				*
+ *									*
+ ************************************************************************/
+
 /**
  * xmlDocDumpMemory:
  * @cur:  the document
@@ -4615,6 +5224,7 @@
     else xmlCompressMode = mode;
 }
 
+#if 0
 /**
  * xmlDocDump:
  * @f:  the FILE*
@@ -4698,4 +5308,128 @@
     xmlBufferFree(buf);
     return(ret * sizeof(xmlChar));
 }
+#else
+/**
+ * xmlDocDump:
+ * @f:  the FILE*
+ * @cur:  the document
+ *
+ * Dump an XML document to an open FILE.
+ *
+ * returns: the number of file written or -1 in case of failure.
+ */
+int
+xmlDocDump(FILE *f, xmlDocPtr cur) {
+    xmlOutputBufferPtr buf;
+    int ret;
 
+    if (cur == NULL) {
+#ifdef DEBUG_TREE
+        fprintf(stderr, "xmlDocDump : document == NULL\n");
+#endif
+	return(-1);
+    }
+    buf = xmlOutputBufferCreateFile(f, NULL);
+    if (buf == NULL) return(-1);
+    xmlDocContentDumpOutput(buf, cur, NULL);
+
+    ret = xmlOutputBufferClose(buf);
+    return(ret);
+}
+
+/**
+ * xmlSaveFile:
+ * @filename:  the filename (or URL)
+ * @cur:  the document
+ *
+ * Dump an XML document to a file. Will use compression if
+ * compiled in and enabled. If @filename is "-" the stdout file is
+ * used.
+ * returns: the number of file written or -1 in case of failure.
+ */
+int
+xmlSaveFile(const char *filename, xmlDocPtr cur) {
+    xmlOutputBufferPtr buf;
+    int ret;
+
+    /* 
+     * save the content to a temp buffer.
+     */
+#ifdef HAVE_ZLIB_H
+    if (cur->compression < 0) cur->compression = xmlCompressMode;
+#endif
+    buf = xmlOutputBufferCreateFilename(filename, NULL, cur->compression);
+    if (buf == NULL) return(0);
+
+    xmlDocContentDumpOutput(buf, cur, NULL);
+
+    ret = xmlOutputBufferClose(buf);
+    return(ret);
+}
+
+/**
+ * xmlSaveFileTo:
+ * @buf:  an output I/O buffer
+ * @cur:  the document
+ * @encoding:  the encoding if any assuming the i/O layer handles the trancoding
+ *
+ * Dump an XML document to an I/O buffer.
+ *
+ * returns: the number of file written or -1 in case of failure.
+ */
+int
+xmlSaveFileTo(xmlOutputBuffer *buf, xmlDocPtr cur, const char *encoding) {
+    int ret;
+
+    if (buf == NULL) return(0);
+    xmlDocContentDumpOutput(buf, cur, encoding);
+    ret = xmlOutputBufferClose(buf);
+    return(ret);
+}
+
+/**
+ * xmlSaveFileEnc:
+ * @filename:  the filename (or URL)
+ * @cur:  the document
+ * @encoding:  the name of an encoding (or NULL)
+ *
+ * Dump an XML document, converting it to the given encoding
+ *
+ * returns: the number of file written or -1 in case of failure.
+ */
+int
+xmlSaveFileEnc(const char *filename, xmlDocPtr cur, const char *encoding) {
+    xmlOutputBufferPtr buf;
+    xmlCharEncodingHandlerPtr handler = NULL;
+    int ret;
+
+    if (encoding != NULL) {
+	xmlCharEncoding enc;
+
+	enc = xmlParseCharEncoding(encoding);
+	if (enc != cur->charset) {
+	    if (cur->charset != XML_CHAR_ENCODING_UTF8) {
+		/*
+		 * Not supported yet
+		 */
+		return(-1);
+	    }
+
+	    handler = xmlFindCharEncodingHandler(encoding);
+	    if (handler == NULL)
+		return(-1);
+	}
+    }
+
+    /* 
+     * save the content to a temp buffer.
+     */
+    buf = xmlOutputBufferCreateFilename(filename, handler, 0);
+    if (buf == NULL) return(0);
+
+    xmlDocContentDumpOutput(buf, cur, encoding);
+
+    ret = xmlOutputBufferClose(buf);
+    return(ret);
+}
+#endif
diff --git a/tree.h b/tree.h
index 35ea525..9c5b280 100644
--- a/tree.h
+++ b/tree.h
@@ -181,6 +181,7 @@
     xmlElementTypeVal      etype;	/* The type */
     xmlElementContentPtr content;	/* the allowed element content */
     xmlAttributePtr   attributes;	/* List of the declared attributes */
+    const xmlChar        *prefix;	/* the namespace prefix if any */
 };
 
 /*
@@ -347,13 +348,23 @@
     struct _xmlDtd  *extSubset;	/* the document external subset */
     struct _xmlNs   *oldNs;	/* Global namespace, the old way */
     const xmlChar  *version;	/* the XML version string */
-    const xmlChar  *encoding;   /* encoding, if any */
+    const xmlChar  *encoding;   /* external initial encoding, if any */
     void           *ids;        /* Hash table for ID attributes if any */
     void           *refs;       /* Hash table for IDREFs attributes if any */
     const xmlChar  *URL;	/* The URI for that document */
+    int             charset;    /* encoding of the in-memory content
+				   actually an xmlCharEncoding */
 };
 
 /*
+ * Compatibility naming layer with libxml1
+ */
+#ifndef xmlChildrenNode
+#define xmlChildrenNode children
+#define xmlRootNode children
+#endif
+
+/*
  * Variables.
  */
 extern xmlNsPtr baseDTD;
@@ -374,6 +385,9 @@
 void		xmlBufferAdd		(xmlBufferPtr buf,
 					 const xmlChar *str,
 					 int len);
+void		xmlBufferAddHead	(xmlBufferPtr buf,
+					 const xmlChar *str,
+					 int len);
 void		xmlBufferCat		(xmlBufferPtr buf,
 					 const xmlChar *str);
 void		xmlBufferCCat		(xmlBufferPtr buf,
@@ -545,6 +559,9 @@
 xmlChar *	xmlNodeListGetString	(xmlDocPtr doc,
 					 xmlNodePtr list,
 					 int inLine);
+xmlChar *	xmlNodeListGetRawString	(xmlDocPtr doc,
+					 xmlNodePtr list,
+					 int inLine);
 void		xmlNodeSetContent	(xmlNodePtr cur,
 					 const xmlChar *content);
 void		xmlNodeSetContentLen	(xmlNodePtr cur,
@@ -591,7 +608,7 @@
 void		xmlDocDumpMemory	(xmlDocPtr cur,
 					 xmlChar**mem,
 					 int *size);
-void		xmlDocDump		(FILE *f,
+int		xmlDocDump		(FILE *f,
 					 xmlDocPtr cur);
 void		xmlElemDump		(FILE *f,
 					 xmlDocPtr doc,
@@ -599,6 +616,17 @@
 int		xmlSaveFile		(const char *filename,
 					 xmlDocPtr cur);
 
+/* This one is exported from xmlIO.h
+ 
+int		xmlSaveFileTo		(xmlOutputBuffer *buf,
+					 xmlDocPtr cur,
+					 const char *encoding);
+ */ 					 
+
+int		xmlSaveFileEnc		(const char *filename,
+					 xmlDocPtr cur,
+					 const char *encoding);
+
 /*
  * Compression
  */
diff --git a/uri.c b/uri.c
index 6000d39..ac7aa0b 100644
--- a/uri.c
+++ b/uri.c
@@ -1513,7 +1513,10 @@
 	val = xmlSaveUri(ref);
 	goto done;
     }
-    res->scheme = xmlMemStrdup(bas->scheme);
+    if (bas->scheme != NULL)
+	res->scheme = xmlMemStrdup(bas->scheme);
+    else
+	res->scheme = NULL;
 
     /*
      * 4) If the authority component is defined, then the reference is a
diff --git a/uri.h b/uri.h
index 59c4467..705e385 100644
--- a/uri.h
+++ b/uri.h
@@ -43,6 +43,8 @@
 xmlChar *	xmlBuildURI		(const xmlChar *URI,
 	                        	 const xmlChar *base);
 xmlURIPtr	xmlParseURI		(const char *URI);
+int		xmlParseURIReference	(xmlURIPtr uri,
+					 const char *str);
 xmlChar *	xmlSaveUri		(xmlURIPtr uri);
 void		xmlPrintURI		(FILE *stream,
 					 xmlURIPtr uri);
diff --git a/valid.c b/valid.c
index bc66ac5..5dc37ed 100644
--- a/valid.c
+++ b/valid.c
@@ -154,6 +154,61 @@
 xmlElementPtr xmlGetDtdElementDesc(xmlDtdPtr dtd, const xmlChar *name);
 xmlAttributePtr xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem);
 
+/************************************************************************
+ *									*
+ *			QName handling helper				*
+ *									*
+ ************************************************************************/
+
+/**
+ * xmlSplitQName2:
+ * @name:  an XML parser context
+ * @prefix:  a xmlChar ** 
+ *
+ * parse an XML qualified name string
+ *
+ * [NS 5] QName ::= (Prefix ':')? LocalPart
+ *
+ * [NS 6] Prefix ::= NCName
+ *
+ * [NS 7] LocalPart ::= NCName
+ *
+ * Returns NULL if not a QName, otherwise the local part, and prefix
+ *   is updated to get the Prefix if any.
+ */
+
+xmlChar *
+xmlSplitQName2(const xmlChar *name, xmlChar **prefix) {
+    int len = 0;
+    xmlChar *ret = NULL;
+
+    *prefix = NULL;
+
+    /* xml: prefix is not really a namespace */
+    if ((name[0] == 'x') && (name[1] == 'm') &&
+        (name[2] == 'l') && (name[3] == ':'))
+	return(NULL);
+
+    /* nasty but valid */
+    if (name[0] == ':')
+	return(NULL);
+
+    /*
+     * we are not trying to validate but just to cut, and yes it will
+     * work even if this is as set of UTF-8 encoded chars
+     */
+    while ((name[len] != 0) && (name[len] != ':')) 
+	len++;
+    
+    if (name[len] == 0)
+	return(NULL);
+
+    *prefix = xmlStrndup(name, len);
+    ret = xmlStrdup(&name[len + 1]);
+
+    return(ret);
+}
+
 /****************************************************************
  *								*
  *	Util functions for data allocation/deallocation		*
@@ -428,6 +483,7 @@
 		  xmlElementContentPtr content) {
     xmlElementPtr ret, cur;
     xmlElementTablePtr table;
+    xmlChar *ns, *uqname;
     int i;
 
     if (dtd == NULL) {
@@ -473,6 +529,13 @@
     }
 
     /*
+     * check if name is a QName
+     */
+    uqname = xmlSplitQName2(name, &ns);
+    if (uqname != NULL)
+	name = uqname;
+
+    /*
      * Create the Element table if needed.
      */
     table = dtd->elements;
@@ -489,7 +552,10 @@
      */
     for (i = 0;i < table->nb_elements;i++) {
         cur = table->table[i];
-	if (!xmlStrcmp(cur->name, name)) {
+	if ((ns != NULL) && (cur->prefix == NULL)) continue;
+	if ((ns == NULL) && (cur->prefix != NULL)) continue;
+	if ((!xmlStrcmp(cur->name, name)) &&
+	    ((ns == NULL) || (!xmlStrcmp(cur->prefix, ns)))) {
 	    /*
 	     * The element is already defined in this Dtd.
 	     */
@@ -527,6 +593,7 @@
      */
     ret->etype = type;
     ret->name = xmlStrdup(name);
+    ret->prefix = ns;
     ret->content = xmlCopyElementContent(content);
     ret->attributes = xmlScanAttributeDecl(dtd, name);
     table->nb_elements++;
@@ -543,6 +610,8 @@
 	ret->prev = dtd->last;
 	dtd->last = (xmlNodePtr) ret;
     }
+    if (uqname != NULL)
+	xmlFree(uqname);
     return(ret);
 }
 
@@ -559,6 +628,8 @@
     xmlFreeElementContent(elem->content);
     if (elem->name != NULL)
 	xmlFree((xmlChar *) elem->name);
+    if (elem->prefix != NULL)
+	xmlFree((xmlChar *) elem->prefix);
     memset(elem, -1, sizeof(xmlElement));
     xmlFree(elem);
 }
@@ -896,7 +967,7 @@
  *
  * Register a new attribute declaration
  *
- * Returns NULL if not, othervise the entity
+ * Returns NULL if not new, othervise the attribute decl
  */
 xmlAttributePtr
 xmlAddAttributeDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *elem,
@@ -981,6 +1052,7 @@
 	     */
 	    VWARNING(ctxt->userData, "Attribute %s on %s: already defined\n",
 		   elem, name);
+	    return(NULL);
 	}
     }
 
@@ -1157,6 +1229,10 @@
     xmlBufferWriteChar(buf, "<!ATTLIST ");
     xmlBufferWriteCHAR(buf, attr->elem);
     xmlBufferWriteChar(buf, " ");
+    if (attr->prefix != NULL) {
+	xmlBufferWriteCHAR(buf, attr->prefix);
+	xmlBufferWriteChar(buf, ":");
+    }
     xmlBufferWriteCHAR(buf, attr->name);
     switch (attr->atype) {
 	case XML_ATTRIBUTE_CDATA:
@@ -2066,6 +2142,7 @@
 xmlGetDtdElementDesc(xmlDtdPtr dtd, const xmlChar *name) {
     xmlElementTablePtr table;
     xmlElementPtr cur;
+    xmlChar *uqname = NULL, *prefix = NULL;
     int i;
 
     if (dtd == NULL) return(NULL);
@@ -2077,6 +2154,59 @@
 	if (!xmlStrcmp(cur->name, name))
 	    return(cur);
     }
+
+    /*
+     * Specific case if name is a QName.
+     */
+    uqname = xmlSplitQName2(name, &prefix);
+    if (uqname == NULL) return(NULL);
+
+    for (i = 0;i < table->nb_elements;i++) {
+        cur = table->table[i];
+	if ((!xmlStrcmp(cur->name, uqname)) &&
+	    ((prefix == cur->prefix) ||
+	     ((prefix != NULL) && (cur->prefix != NULL) &&
+	      (!xmlStrcmp(cur->prefix, prefix))))) {
+	    if (prefix != NULL) xmlFree(prefix);
+	    if (uqname != NULL) xmlFree(uqname);
+	    return(cur);
+	}
+    }
+    if (prefix != NULL) xmlFree(prefix);
+    if (uqname != NULL) xmlFree(uqname);
+    return(NULL);
+}
+
+/**
+ * xmlGetDtdQElementDesc:
+ * @dtd:  a pointer to the DtD to search
+ * @name:  the element name
+ * @prefix:  the element namespace prefix
+ *
+ * Search the Dtd for the description of this element
+ *
+ * returns the xmlElementPtr if found or NULL
+ */
+
+xmlElementPtr
+xmlGetDtdQElementDesc(xmlDtdPtr dtd, const xmlChar *name,
+	              const xmlChar *prefix) {
+    xmlElementTablePtr table;
+    xmlElementPtr cur;
+    int i;
+
+    if (dtd == NULL) return(NULL);
+    if (dtd->elements == NULL) return(NULL);
+    table = dtd->elements;
+
+    for (i = 0;i < table->nb_elements;i++) {
+        cur = table->table[i];
+	if (!xmlStrcmp(cur->name, name) &&
+	    ((prefix == cur->prefix) ||
+	     ((prefix != NULL) && (cur->prefix != NULL) &&
+	      (!xmlStrcmp(cur->prefix, prefix)))))
+	    return(cur);
+    }
     return(NULL);
 }
 
@@ -2096,6 +2226,7 @@
 xmlGetDtdAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name) {
     xmlAttributeTablePtr table;
     xmlAttributePtr cur;
+    xmlChar *uqname = NULL, *prefix = NULL;
     int i;
 
     if (dtd == NULL) return(NULL);
@@ -2108,6 +2239,63 @@
 	    (!xmlStrcmp(cur->elem, elem)))
 	    return(cur);
     }
+
+    /*
+     * Specific case if name is a QName.
+     */
+    uqname = xmlSplitQName2(name, &prefix);
+    if (uqname == NULL) return(NULL);
+
+    for (i = 0;i < table->nb_attributes;i++) {
+        cur = table->table[i];
+	if ((!xmlStrcmp(cur->name, uqname)) &&
+	    (!xmlStrcmp(cur->elem, elem)) &&
+	    ((prefix == cur->prefix) ||
+	     ((prefix != NULL) && (cur->prefix != NULL) &&
+	      (!xmlStrcmp(cur->prefix, prefix))))) {
+	    if (prefix != NULL) xmlFree(prefix);
+	    if (uqname != NULL) xmlFree(uqname);
+	    return(cur);
+	}
+    }
+    if (prefix != NULL) xmlFree(prefix);
+    if (uqname != NULL) xmlFree(uqname);
+    return(NULL);
+}
+
+/**
+ * xmlGetDtdQAttrDesc:
+ * @dtd:  a pointer to the DtD to search
+ * @elem:  the element name
+ * @name:  the attribute name
+ * @prefix:  the attribute namespace prefix
+ *
+ * Search the Dtd for the description of this qualified attribute on
+ * this element.
+ *
+ * returns the xmlAttributePtr if found or NULL
+ */
+
+xmlAttributePtr
+xmlGetDtdQAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name,
+	          const xmlChar *prefix) {
+    xmlAttributeTablePtr table;
+    xmlAttributePtr cur;
+    int i;
+
+    if (dtd == NULL) return(NULL);
+    if (dtd->attributes == NULL) return(NULL);
+    table = dtd->attributes;
+
+    for (i = 0;i < table->nb_attributes;i++) {
+        cur = table->table[i];
+	if ((!xmlStrcmp(cur->name, name)) &&
+	    (!xmlStrcmp(cur->elem, elem)) &&
+	    ((prefix == cur->prefix) ||
+	     ((prefix != NULL) && (cur->prefix != NULL) &&
+	      (!xmlStrcmp(cur->prefix, prefix)))))
+	    return(cur);
+    }
     return(NULL);
 }
 
@@ -2586,13 +2774,25 @@
 			        const xmlChar *name, const xmlChar *value) {
     xmlChar *ret, *dst;
     const xmlChar *src;
-    xmlAttributePtr attrDecl;
+    xmlAttributePtr attrDecl = NULL;
 
     if (doc == NULL) return(NULL);
     if (elem == NULL) return(NULL);
     if (name == NULL) return(NULL);
     if (value == NULL) return(NULL);
 
+    if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
+	xmlChar qname[500];
+#ifdef HAVE_SNPRINTF
+	snprintf((char *) qname, sizeof(qname), "%s:%s",
+		 elem->ns->prefix, elem->name);
+#else
+	sprintf(qname, "%s:%s", elem->name, elem->ns->prefix);
+#endif
+	attrDecl = xmlGetDtdAttrDesc(doc->intSubset, qname, name);
+	if ((attrDecl == NULL) && (doc->extSubset != NULL))
+	    attrDecl = xmlGetDtdAttrDesc(doc->extSubset, qname, name);
+    }
     attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, name);
     if ((attrDecl == NULL) && (doc->extSubset != NULL))
 	attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name, name);
@@ -2850,7 +3050,7 @@
 xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
                         xmlNodePtr elem, xmlAttrPtr attr, const xmlChar *value) {
     /* xmlElementPtr elemDecl; */
-    xmlAttributePtr attrDecl;
+    xmlAttributePtr attrDecl =  NULL;
     int val;
     int ret = 1;
 
@@ -2858,9 +3058,42 @@
     if ((elem == NULL) || (elem->name == NULL)) return(0);
     if ((attr == NULL) || (attr->name == NULL)) return(0);
 
-    attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, attr->name);
-    if ((attrDecl == NULL) && (doc->extSubset != NULL))
-	attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name, attr->name);
+    if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
+	xmlChar qname[500];
+#ifdef HAVE_SNPRINTF
+	snprintf((char *) qname, sizeof(qname), "%s:%s",
+		 elem->ns->prefix, elem->name);
+#else
+	sprintf(qname, "%s:%s", elem->name, elem->ns->prefix);
+#endif
+	if (attr->ns != NULL) {
+	    attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, qname,
+		                          attr->name, attr->ns->prefix);
+	    if ((attrDecl == NULL) && (doc->extSubset != NULL))
+		attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, qname,
+					      attr->name, attr->ns->prefix);
+	} else {
+	    attrDecl = xmlGetDtdAttrDesc(doc->intSubset, qname, attr->name);
+	    if ((attrDecl == NULL) && (doc->extSubset != NULL))
+		attrDecl = xmlGetDtdAttrDesc(doc->extSubset,
+					     qname, attr->name);
+	}
+    }
+    if (attrDecl == NULL) {
+	if (attr->ns != NULL) {
+	    attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, elem->name,
+		                          attr->name, attr->ns->prefix);
+	    if ((attrDecl == NULL) && (doc->extSubset != NULL))
+		attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, elem->name,
+					      attr->name, attr->ns->prefix);
+	} else {
+	    attrDecl = xmlGetDtdAttrDesc(doc->intSubset,
+		                         elem->name, attr->name);
+	    if ((attrDecl == NULL) && (doc->extSubset != NULL))
+		attrDecl = xmlGetDtdAttrDesc(doc->extSubset,
+					     elem->name, attr->name);
+	}
+    }
 
 
     /* Validity Constraint: Attribute Value Type */
@@ -3274,7 +3507,7 @@
 int
 xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
                       xmlNodePtr elem) {
-    xmlElementPtr elemDecl;
+    xmlElementPtr elemDecl = NULL;
     xmlElementContentPtr cont;
     xmlAttributePtr attr;
     xmlNodePtr child;
@@ -3347,9 +3580,25 @@
     }
     if (elem->name == NULL) return(0);
 
-    elemDecl = xmlGetDtdElementDesc(doc->intSubset, elem->name);
-    if ((elemDecl == NULL) && (doc->extSubset != NULL))
-	elemDecl = xmlGetDtdElementDesc(doc->extSubset, elem->name);
+    /*
+     * Fetch the declaration for the qualified name
+     */
+    if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
+	elemDecl = xmlGetDtdQElementDesc(doc->intSubset,
+		                         elem->name, elem->ns->prefix);
+	if ((elemDecl == NULL) && (doc->extSubset != NULL))
+	    elemDecl = xmlGetDtdQElementDesc(doc->extSubset,
+		                             elem->name, elem->ns->prefix);
+    }
+
+    /*
+     * Fetch the declaration for the non qualified name
+     */
+    if (elemDecl == NULL) {
+	elemDecl = xmlGetDtdElementDesc(doc->intSubset, elem->name);
+	if ((elemDecl == NULL) && (doc->extSubset != NULL))
+	    elemDecl = xmlGetDtdElementDesc(doc->extSubset, elem->name);
+    }
     if (elemDecl == NULL) {
 	VERROR(ctxt->userData, "No declaration for element %s\n",
 	       elem->name);
@@ -3375,6 +3624,34 @@
 	    while (child != NULL) {
 	        if (child->type == XML_ELEMENT_NODE) {
 		    name = child->name;
+		    if ((child->ns != NULL) && (child->ns->prefix != NULL)) {
+			xmlChar qname[500];
+#ifdef HAVE_SNPRINTF
+			snprintf((char *) qname, sizeof(qname), "%s:%s",
+				 child->ns->prefix, child->name);
+#else
+			sprintf(qname, "%s:%s", child->name, child->ns->prefix);
+#endif
+			cont = elemDecl->content;
+			while (cont != NULL) {
+			    if (cont->type == XML_ELEMENT_CONTENT_ELEMENT) {
+				if (!xmlStrcmp(cont->name, qname)) break;
+			    } else if ((cont->type == XML_ELEMENT_CONTENT_OR) &&
+			       (cont->c1 != NULL) &&
+			       (cont->c1->type == XML_ELEMENT_CONTENT_ELEMENT)){
+				if (!xmlStrcmp(cont->c1->name, qname)) break;
+			    } else if ((cont->type != XML_ELEMENT_CONTENT_OR) ||
+				(cont->c1 == NULL) ||
+				(cont->c1->type != XML_ELEMENT_CONTENT_PCDATA)){
+				/* Internal error !!! */
+				fprintf(stderr, "Internal: MIXED struct bad\n");
+				break;
+			    }
+			    cont = cont->c2;
+			}
+			if (cont != NULL)
+			    goto child_ok;
+		    }
 		    cont = elemDecl->content;
 		    while (cont != NULL) {
 		        if (cont->type == XML_ELEMENT_CONTENT_ELEMENT) {
@@ -3399,6 +3676,7 @@
 			ret = 0;
 		    }
 		}
+child_ok:
 	        child = child->next;
 	    }
 	    break;
@@ -3518,15 +3796,32 @@
 	VERROR(ctxt->userData, "Not valid: no root element\n");
         return(0);
     }
+
+    /*
+     * Check first the document root against the NQName
+     */
     if (xmlStrcmp(doc->intSubset->name, root->name)) {
-	if ((xmlStrcmp(doc->intSubset->name, BAD_CAST "HTML")) ||
-	    (xmlStrcmp(root->name, BAD_CAST "html"))) {
-	    VERROR(ctxt->userData,
-		   "Not valid: root and DtD name do not match '%s' and '%s'\n",
-		   root->name, doc->intSubset->name);
-	    return(0);
-	}
+	if ((root->ns != NULL) && (root->ns->prefix != NULL)) {
+	    xmlChar qname[500];
+#ifdef HAVE_SNPRINTF
+	    snprintf((char *) qname, sizeof(qname), "%s:%s",
+		     root->ns->prefix, root->name);
+#else
+	    sprintf(qname, "%s:%s", root->name, root->ns->prefix);
+#endif
+	    if (!xmlStrcmp(doc->intSubset->name, qname))
+		goto name_ok;
+	} 
+	if ((!xmlStrcmp(doc->intSubset->name, BAD_CAST "HTML")) &&
+	    (!xmlStrcmp(root->name, BAD_CAST "html")))
+	    goto name_ok;
+	VERROR(ctxt->userData,
+	       "Not valid: root and DtD name do not match '%s' and '%s'\n",
+	       root->name, doc->intSubset->name);
+	return(0);
+	
     }
+name_ok:
     return(1);
 }
 
diff --git a/xmlIO.c b/xmlIO.c
index 841a6b6..fdf961c 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -41,9 +41,9 @@
 #include <libxml/nanohttp.h>
 #include <libxml/nanoftp.h>
 
-/* #define DEBUG_INPUT */
 /* #define VERBOSE_FAILURE */
 /* #define DEBUG_EXTERNAL_ENTITIES */
+/* #define DEBUG_INPUT */
 
 #ifdef DEBUG_INPUT
 #define MINLEN 40
@@ -67,6 +67,22 @@
 int xmlInputCallbackNr = 0;
 int xmlInputCallbackInitialized = 0;
 
+/*
+ * Output I/O callback sets
+ */
+typedef struct _xmlOutputCallback {
+    xmlOutputMatchCallback matchcallback;
+    xmlOutputOpenCallback opencallback;
+    xmlOutputWriteCallback writecallback;
+    xmlOutputCloseCallback closecallback;
+} xmlOutputCallback;
+
+#define MAX_OUTPUT_CALLBACK 15
+
+xmlOutputCallback xmlOutputCallbackTable[MAX_OUTPUT_CALLBACK];
+int xmlOutputCallbackNr = 0;
+int xmlOutputCallbackInitialized = 0;
+
 /************************************************************************
  *									*
  *		Standard I/O for file accesses				*
@@ -124,10 +140,43 @@
 }
 
 /**
+ * xmlFdOpenW:
+ * @filename:  the URI for matching
+ *
+ * input from file descriptor,
+ * if @filename is "-" then the standard output is used
+ *
+ * Returns an I/O context or NULL in case of error
+ */
+void *
+xmlFdOpenW (const char *filename) {
+    const char *path = NULL;
+    int fd;
+
+    if (!strcmp(filename, "-")) {
+	fd = 1;
+	return((void *) fd);
+    }
+
+    if (!strncmp(filename, "file://localhost", 16))
+	path = &filename[16];
+    else if (!strncmp(filename, "file:///", 8))
+	path = &filename[8];
+    else if (filename[0] == '/')
+	path = filename;
+    if (path == NULL)
+	return(NULL);
+
+    fd = open (filename, O_WRONLY);
+
+    return((void *) fd);
+}
+
+/**
  * xmlFdRead:
  * @context:  the I/O context
  * @buffer:  where to drop data
- * @len:  number of bytes to write
+ * @len:  number of bytes to read
  *
  * Read @len bytes to @buffer from the I/O channel.
  *
@@ -139,6 +188,21 @@
 }
 
 /**
+ * xmlFdWrite:
+ * @context:  the I/O context
+ * @buffer:  where to get data
+ * @len:  number of bytes to write
+ *
+ * Write @len bytes from @buffer to the I/O channel.
+ *
+ * Returns the number of bytes written
+ */
+int
+xmlFdWrite (void * context, const char * buffer, int len) {
+    return(write((int) context, &buffer[0], len));
+}
+
+/**
  * xmlFdClose:
  * @context:  the I/O context
  *
@@ -199,6 +263,38 @@
 }
 
 /**
+ * xmlFileOpenW:
+ * @filename:  the URI for matching
+ *
+ * output to from FILE *,
+ * if @filename is "-" then the standard output is used
+ *
+ * Returns an I/O context or NULL in case of error
+ */
+void *
+xmlFileOpenW (const char *filename) {
+    const char *path = NULL;
+    FILE *fd;
+
+    if (!strcmp(filename, "-")) {
+	fd = stdout;
+	return((void *) fd);
+    }
+
+    if (!strncmp(filename, "file://localhost", 16))
+	path = &filename[16];
+    else if (!strncmp(filename, "file:///", 8))
+	path = &filename[8];
+    else 
+	path = filename;
+    if (path == NULL)
+	return(NULL);
+
+    fd = fopen(path, "w");
+    return((void *) fd);
+}
+
+/**
  * xmlFileRead:
  * @context:  the I/O context
  * @buffer:  where to drop data
@@ -214,6 +310,21 @@
 }
 
 /**
+ * xmlFileWrite:
+ * @context:  the I/O context
+ * @buffer:  where to drop data
+ * @len:  number of bytes to write
+ *
+ * Write @len bytes from @buffer to the I/O channel.
+ *
+ * Returns the number of bytes written
+ */
+int
+xmlFileWrite (void * context, const char * buffer, int len) {
+    return(fwrite(&buffer[0], 1,  len, (FILE *) context));
+}
+
+/**
  * xmlFileClose:
  * @context:  the I/O context
  *
@@ -274,6 +385,39 @@
 }
 
 /**
+ * xmlGzfileOpenW:
+ * @filename:  the URI for matching
+ * @compression:  the compression factor (0 - 9 included)
+ *
+ * input from compressed file open
+ * if @filename is " " then the standard input is used
+ *
+ * Returns an I/O context or NULL in case of error
+ */
+void *
+xmlGzfileOpenW (const char *filename, int compression) {
+    const char *path = NULL;
+    char mode[15];
+    gzFile fd;
+
+    sprintf(mode, "w%d", compression);
+    if (!strcmp(filename, "-")) {
+        fd = gzdopen(1, mode);
+	return((void *) fd);
+    }
+
+    if (!strncmp(filename, "file://localhost", 16))
+	path = &filename[16];
+    else if (!strncmp(filename, "file:///", 8))
+	path = &filename[8];
+    else 
+	path = filename;
+
+    fd = gzopen(filename, mode);
+    return((void *) fd);
+}
+
+/**
  * xmlGzfileRead:
  * @context:  the I/O context
  * @buffer:  where to drop data
@@ -289,6 +433,21 @@
 }
 
 /**
+ * xmlGzfileWrite:
+ * @context:  the I/O context
+ * @buffer:  where to drop data
+ * @len:  number of bytes to write
+ *
+ * Write @len bytes from @buffer to the compressed I/O channel.
+ *
+ * Returns the number of bytes written
+ */
+int
+xmlGzfileWrite (void * context, const char * buffer, int len) {
+    return(gzwrite((gzFile) context, (char *) &buffer[0], len));
+}
+
+/**
  * xmlGzfileClose:
  * @context:  the I/O context
  *
@@ -449,6 +608,31 @@
 }
 
 /**
+ * xmlRegisterOutputCallbacks:
+ * @match:  the xmlOutputMatchCallback
+ * @open:  the xmlOutputOpenCallback
+ * @write:  the xmlOutputWriteCallback
+ * @close:  the xmlOutputCloseCallback
+ *
+ * Register a new set of I/O callback for handling output.
+ *
+ * Returns the registered handler number or -1 in case of error
+ */
+int
+xmlRegisterOutputCallbacks(xmlOutputMatchCallback match,
+	xmlOutputOpenCallback open, xmlOutputWriteCallback write,
+	xmlOutputCloseCallback close) {
+    if (xmlOutputCallbackNr >= MAX_INPUT_CALLBACK) {
+	return(-1);
+    }
+    xmlOutputCallbackTable[xmlOutputCallbackNr].matchcallback = match;
+    xmlOutputCallbackTable[xmlOutputCallbackNr].opencallback = open;
+    xmlOutputCallbackTable[xmlOutputCallbackNr].writecallback = write;
+    xmlOutputCallbackTable[xmlOutputCallbackNr].closecallback = close;
+    return(xmlOutputCallbackNr++);
+}
+
+/**
  * xmlRegisterDefaultInputCallbacks:
  *
  * Registers the default compiled-in I/O handlers.
@@ -474,6 +658,39 @@
 }
 
 /**
+ * xmlRegisterDefaultOutputCallbacks:
+ *
+ * Registers the default compiled-in I/O handlers.
+ */
+void
+xmlRegisterDefaultOutputCallbacks(void) {
+    xmlRegisterOutputCallbacks(xmlFileMatch, xmlFileOpenW,
+	                      xmlFileWrite, xmlFileClose);
+/*********************************
+ No way a-priori to distinguish between gzipped files from
+ uncompressed ones except opening if existing then closing
+ and saving with same compression ratio ... a pain.
+
+#ifdef HAVE_ZLIB_H
+    xmlRegisterOutputCallbacks(xmlGzfileMatch, xmlGzfileOpen,
+	                       xmlGzfileWrite, xmlGzfileClose);
+#endif
+ No HTTP PUT support yet, patches welcome
+
+#ifdef LIBXML_HTTP_ENABLED
+    xmlRegisterOutputCallbacks(xmlIOHTTPMatch, xmlIOHTTPOpen,
+	                       xmlIOHTTPWrite, xmlIOHTTPClose);
+#endif
+
+ Nor FTP PUT ....
+#ifdef LIBXML_FTP_ENABLED
+    xmlRegisterOutputCallbacks(xmlIOFTPMatch, xmlIOFTPOpen,
+	                       xmlIOFTPWrite, xmlIOFTPClose);
+#endif
+ **********************************/
+}
+
+/**
  * xmlAllocParserInputBuffer:
  * @enc:  the charset encoding if known
  *
@@ -510,6 +727,47 @@
 }
 
 /**
+ * xmlAllocOutputBuffer:
+ * @encoder:  the encoding converter or NULL
+ *
+ * Create a buffered parser output
+ *
+ * Returns the new parser output or NULL
+ */
+xmlOutputBufferPtr
+xmlAllocOutputBuffer(xmlCharEncodingHandlerPtr encoder) {
+    xmlOutputBufferPtr ret;
+
+    ret = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer));
+    if (ret == NULL) {
+        fprintf(stderr, "xmlAllocOutputBuffer : out of memory!\n");
+	return(NULL);
+    }
+    memset(ret, 0, (size_t) sizeof(xmlOutputBuffer));
+    ret->buffer = xmlBufferCreate();
+    if (ret->buffer == NULL) {
+        xmlFree(ret);
+	return(NULL);
+    }
+    ret->buffer->alloc = XML_BUFFER_ALLOC_DOUBLEIT;
+    ret->encoder = encoder;
+    if (encoder != NULL) {
+        ret->conv = xmlBufferCreateSize(4000);
+	/*
+	 * This call is designed to initiate the encoder state
+	 */
+	xmlCharEncOutFunc(encoder, ret->conv, NULL); 
+    } else
+        ret->conv = NULL;
+    ret->writecallback = NULL;
+    ret->closecallback = NULL;
+    ret->context = NULL;
+    ret->written = 0;
+
+    return(ret);
+}
+
+/**
  * xmlFreeParserInputBuffer:
  * @in:  a buffered parser input
  *
@@ -537,6 +795,43 @@
 }
 
 /**
+ * xmlOutputBufferClose:
+ * @out:  a buffered output
+ *
+ * flushes and close the output I/O channel
+ * and free up all the associated resources
+ *
+ * Returns the number of byte written or -1 in case of error.
+ */
+int
+xmlOutputBufferClose(xmlOutputBufferPtr out) {
+    int written;
+
+    if (out == NULL)
+        return(-1);
+    xmlOutputBufferFlush(out);
+    if (out->closecallback != NULL) {
+	out->closecallback(out->context);
+    }
+    written = out->written;
+    if (out->conv) {
+        xmlBufferFree(out->conv);
+	out->conv = NULL;
+    }
+    if (out->encoder != NULL) {
+        xmlCharEncCloseFunc(out->encoder);
+    }
+    if (out->buffer != NULL) {
+        xmlBufferFree(out->buffer);
+	out->buffer = NULL;
+    }
+
+    memset(out, 0xbe, (size_t) sizeof(xmlOutputBuffer));
+    xmlFree(out);
+    return(written);
+}
+
+/**
  * xmlParserInputBufferCreateFilename:
  * @URI:  a C string containing the URI or filename
  * @enc:  the charset encoding if known
@@ -592,6 +887,80 @@
 }
 
 /**
+ * xmlOutputBufferCreateFilename:
+ * @URI:  a C string containing the URI or filename
+ * @encoder:  the encoding converter or NULL
+ * @compression:  the compression ration (0 none, 9 max).
+ *
+ * Create a buffered  output for the progressive saving of a file
+ * If filename is "-' then we use stdout as the output.
+ * Automatic support for ZLIB/Compress compressed document is provided
+ * by default if found at compile-time.
+ * TODO: currently if compression is set, the library only support
+ *       writing to a local file.
+ *
+ * Returns the new output or NULL
+ */
+xmlOutputBufferPtr
+xmlOutputBufferCreateFilename(const char *URI,
+                              xmlCharEncodingHandlerPtr encoder,
+			      int compression) {
+    xmlOutputBufferPtr ret;
+    int i;
+    void *context = NULL;
+
+    if (xmlOutputCallbackInitialized == 0)
+	xmlRegisterDefaultOutputCallbacks();
+
+    if (URI == NULL) return(NULL);
+
+#ifdef HAVE_ZLIB_H
+    if ((compression > 0) && (compression <= 9)) {
+        context = xmlGzfileOpenW(URI, compression);
+	if (context != NULL) {
+	    ret = xmlAllocOutputBuffer(encoder);
+	    if (ret != NULL) {
+		ret->context = context;
+		ret->writecallback = xmlGzfileWrite;
+		ret->closecallback = xmlGzfileClose;
+	    }
+	    return(ret);
+	}
+    }
+#endif
+
+    /*
+     * Try to find one of the output accept method accepting taht scheme
+     * Go in reverse to give precedence to user defined handlers.
+     */
+    for (i = xmlOutputCallbackNr - 1;i >= 0;i--) {
+	if ((xmlOutputCallbackTable[i].matchcallback != NULL) &&
+	    (xmlOutputCallbackTable[i].matchcallback(URI) != 0)) {
+	    context = xmlOutputCallbackTable[i].opencallback(URI);
+	    if (context != NULL)
+		break;
+	}
+    }
+    if (context == NULL) {
+#ifdef DEBUG_INPUT
+	fprintf(stderr, "No output filter matching \"%s\"\n", URI);
+#endif
+	return(NULL);
+    }
+
+    /*
+     * Allocate the Output buffer front-end.
+     */
+    ret = xmlAllocOutputBuffer(encoder);
+    if (ret != NULL) {
+	ret->context = context;
+	ret->writecallback = xmlOutputCallbackTable[i].writecallback;
+	ret->closecallback = xmlOutputCallbackTable[i].closecallback;
+    }
+    return(ret);
+}
+
+/**
  * xmlParserInputBufferCreateFile:
  * @file:  a FILE* 
  * @enc:  the charset encoding if known
@@ -621,6 +990,35 @@
 }
 
 /**
+ * xmlOutputBufferCreateFile:
+ * @file:  a FILE* 
+ * @encoder:  the encoding converter or NULL
+ *
+ * Create a buffered output for the progressive saving to a FILE *
+ * buffered C I/O
+ *
+ * Returns the new parser output or NULL
+ */
+xmlOutputBufferPtr
+xmlOutputBufferCreateFile(FILE *file, xmlCharEncodingHandlerPtr encoder) {
+    xmlOutputBufferPtr ret;
+
+    if (xmlOutputCallbackInitialized == 0)
+	xmlRegisterDefaultOutputCallbacks();
+
+    if (file == NULL) return(NULL);
+
+    ret = xmlAllocOutputBuffer(encoder);
+    if (ret != NULL) {
+        ret->context = file;
+	ret->writecallback = xmlFileWrite;
+	ret->closecallback = xmlFileClose;
+    }
+
+    return(ret);
+}
+
+/**
  * xmlParserInputBufferCreateFd:
  * @fd:  a file descriptor number
  * @enc:  the charset encoding if known
@@ -647,6 +1045,32 @@
 }
 
 /**
+ * xmlOutputBufferCreateFd:
+ * @fd:  a file descriptor number
+ * @encoder:  the encoding converter or NULL
+ *
+ * Create a buffered output for the progressive saving 
+ * to a file descriptor
+ *
+ * Returns the new parser output or NULL
+ */
+xmlOutputBufferPtr
+xmlOutputBufferCreateFd(int fd, xmlCharEncodingHandlerPtr encoder) {
+    xmlOutputBufferPtr ret;
+
+    if (fd < 0) return(NULL);
+
+    ret = xmlAllocOutputBuffer(encoder);
+    if (ret != NULL) {
+        ret->context = (void *) fd;
+	ret->writecallback = xmlFdWrite;
+	ret->closecallback = xmlFdClose;
+    }
+
+    return(ret);
+}
+
+/**
  * xmlParserInputBufferCreateIO:
  * @ioread:  an I/O read function
  * @ioclose:  an I/O close function
@@ -654,7 +1078,7 @@
  * @enc:  the charset encoding if known
  *
  * Create a buffered parser input for the progressive parsing for the input
- * from a file descriptor
+ * from an I/O handler
  *
  * Returns the new parser input or NULL
  */
@@ -676,10 +1100,40 @@
 }
 
 /**
+ * xmlOutputBufferCreateIO:
+ * @iowrite:  an I/O write function
+ * @ioclose:  an I/O close function
+ * @ioctx:  an I/O handler
+ * @enc:  the charset encoding if known
+ *
+ * Create a buffered output for the progressive saving
+ * to an I/O handler
+ *
+ * Returns the new parser output or NULL
+ */
+xmlOutputBufferPtr
+xmlOutputBufferCreateIO(xmlOutputWriteCallback   iowrite,
+	 xmlOutputCloseCallback  ioclose, void *ioctx,
+	 xmlCharEncodingHandlerPtr encoder) {
+    xmlOutputBufferPtr ret;
+
+    if (iowrite == NULL) return(NULL);
+
+    ret = xmlAllocOutputBuffer(encoder);
+    if (ret != NULL) {
+        ret->context = (void *) ioctx;
+	ret->writecallback = iowrite;
+	ret->closecallback = ioclose;
+    }
+
+    return(ret);
+}
+
+/**
  * xmlParserInputBufferPush:
  * @in:  a buffered parser input
- * @buf:  an char array
  * @len:  the size in bytes of the array.
+ * @buf:  an char array
  *
  * Push the content of the arry in the input buffer
  * This routine handle the I18N transcoding to internal UTF-8
@@ -769,16 +1223,12 @@
 	xmlFree(buffer);
 	return(-1);
     }
-
-    if (res == 0) {
-	xmlFree(buffer);
-        return(0);
-    }
     if (res < 0) {
 	perror ("read error");
 	xmlFree(buffer);
 	return(-1);
     }
+    len = res;
     if (in->encoder != NULL) {
         /*
 	 * Store the data in the incoming raw buffer
@@ -797,7 +1247,7 @@
 	    return(-1);
 	}
     } else {
-	nbchars = res;
+	nbchars = len;
         buffer[nbchars] = 0;
         xmlBufferAdd(in->buffer, (xmlChar *) buffer, nbchars);
     }
@@ -827,7 +1277,162 @@
     if (in->readcallback != NULL)
 	return(xmlParserInputBufferGrow(in, len));
     else
-        return(0);
+        return(-1);
+}
+
+/**
+ * xmlOutputBufferWrite:
+ * @out:  a buffered parser output
+ * @len:  the size in bytes of the array.
+ * @buf:  an char array
+ *
+ * Write the content of the array in the output I/O buffer
+ * This routine handle the I18N transcoding from internal UTF-8
+ * The buffer is lossless, i.e. will store in case of partial
+ * or delayed writes.
+ *
+ * Returns the number of chars immediately written, or -1
+ *         in case of error.
+ */
+int
+xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *buf) {
+    int nbchars = 0, ret;
+
+    if (len < 0) return(0);
+
+    /*
+     * first handle encoding stuff.
+     */
+    if (out->encoder != NULL) {
+        /*
+	 * Store the data in the incoming raw buffer
+	 */
+        if (out->conv == NULL) {
+	    out->conv = xmlBufferCreate();
+	}
+	xmlBufferAdd(out->buffer, (const xmlChar *) buf, len);
+
+        if (out->buffer->use < MINLEN)
+	    return(0);
+
+	/*
+	 * convert as much as possible to the parser reading buffer.
+	 */
+	nbchars = xmlCharEncOutFunc(out->encoder, out->conv, out->buffer);
+	if (nbchars < 0) {
+	    fprintf(stderr, "xmlOutputBufferWrite: encoder error\n");
+	    return(-1);
+	}
+	nbchars = out->conv->use;
+    } else {
+	xmlBufferAdd(out->buffer, (const xmlChar *) buf, len);
+	nbchars = out->buffer->use;
+    }
+    if (nbchars < MINLEN)
+	return(0);
+
+    /*
+     * second write the stuff to the I/O channel
+     */
+    if (out->encoder != NULL) {
+	ret = out->writecallback(out->context, 
+                             (const char *)out->conv->content, nbchars);
+	if (ret >= 0)
+	    xmlBufferShrink(out->conv, nbchars);
+    } else {
+	ret = out->writecallback(out->context, 
+                             (const char *)out->buffer->content, nbchars);
+	if (ret >= 0)
+	    xmlBufferShrink(out->buffer, nbchars);
+    }
+    if (ret < 0) {
+        fprintf(stderr, "I/O: error %d writing %d bytes\n", ret, nbchars);
+	return(ret);
+    }
+    out->written += ret;
+
+#ifdef DEBUG_INPUT
+    fprintf(stderr, "I/O: wrote %d chars\n", ret);
+#endif
+    return(nbchars);
+}
+
+/**
+ * xmlOutputBufferWriteString:
+ * @out:  a buffered parser output
+ * @str:  a zero terminated C string
+ *
+ * Write the content of the string in the output I/O buffer
+ * This routine handle the I18N transcoding from internal UTF-8
+ * The buffer is lossless, i.e. will store in case of partial
+ * or delayed writes.
+ *
+ * Returns the number of chars immediately written, or -1
+ *         in case of error.
+ */
+int
+xmlOutputBufferWriteString(xmlOutputBufferPtr out, const char *str) {
+    int len;
+    
+    if (str == NULL)
+        return(-1);
+    len = strlen(str);
+
+    if (len > 0)
+	return(xmlOutputBufferWrite(out, len, str));
+    return(len);
+}
+
+/**
+ * xmlOutputBufferFlush:
+ * @out:  a buffered output
+ *
+ * flushes the output I/O channel
+ *
+ * Returns the number of byte written or -1 in case of error.
+ */
+int
+xmlOutputBufferFlush(xmlOutputBufferPtr out) {
+    int nbchars = 0, ret;
+
+    /*
+     * first handle encoding stuff.
+     */
+    if ((out->conv != NULL) && (out->encoder != NULL)) {
+	/*
+	 * convert as much as possible to the parser reading buffer.
+	 */
+	nbchars = xmlCharEncOutFunc(out->encoder, out->conv, out->buffer);
+	if (nbchars < 0) {
+	    fprintf(stderr, "xmlOutputBufferWrite: encoder error\n");
+	    return(-1);
+	}
+    }
+
+    /*
+     * second flush the stuff to the I/O channel
+     */
+    if ((out->conv != NULL) && (out->encoder != NULL)) {
+	ret = out->writecallback(out->context,
+	           (const char *)out->conv->content, out->conv->use);
+	if (ret >= 0)
+	    xmlBufferShrink(out->conv, ret);
+    } else {
+	ret = out->writecallback(out->context,
+	           (const char *)out->buffer->content, out->buffer->use);
+	if (ret >= 0)
+	    xmlBufferShrink(out->buffer, ret);
+    }
+    if (ret < 0) {
+        fprintf(stderr, "I/O: error %d flushing %d bytes\n", ret, nbchars);
+	return(ret);
+    }
+    out->written += ret;
+
+#ifdef DEBUG_INPUT
+    fprintf(stderr, "I/O: flushed %d chars\n", ret);
+#endif
+    return(ret);
 }
 
 /*
diff --git a/xmlIO.h b/xmlIO.h
index 2d14ebe..5289367 100644
--- a/xmlIO.h
+++ b/xmlIO.h
@@ -18,6 +18,11 @@
 extern "C" {
 #endif
 
+/*
+ * Those are the functions and datatypes for the parser input
+ * I/O structures.
+ */
+
 typedef int (*xmlInputMatchCallback) (char const *filename);
 typedef void * (*xmlInputOpenCallback) (char const *filename);
 typedef int (*xmlInputReadCallback) (void * context, char * buffer, int len);
@@ -32,13 +37,38 @@
     
     xmlCharEncodingHandlerPtr encoder; /* I18N conversions to UTF-8 */
     
-    xmlBufferPtr buffer;    /* Local buffer encoded in  UTF-8 */
+    xmlBufferPtr buffer;    /* Local buffer encoded in UTF-8 or ISOLatin */
     xmlBufferPtr raw;       /* if encoder != NULL buffer for raw input */
 };
 
 
 /*
- * Interfaces
+ * Those are the functions and datatypes for the library output
+ * I/O structures.
+ */
+
+typedef int (*xmlOutputMatchCallback) (char const *filename);
+typedef void * (*xmlOutputOpenCallback) (char const *filename);
+typedef int (*xmlOutputWriteCallback) (void * context, const char * buffer,
+                                       int len);
+typedef void (*xmlOutputCloseCallback) (void * context);
+
+typedef struct _xmlOutputBuffer xmlOutputBuffer;
+typedef xmlOutputBuffer *xmlOutputBufferPtr;
+struct _xmlOutputBuffer {
+    void*                   context;
+    xmlOutputWriteCallback  writecallback;
+    xmlOutputCloseCallback  closecallback;
+    
+    xmlCharEncodingHandlerPtr encoder; /* I18N conversions to UTF-8 */
+    
+    xmlBufferPtr buffer;    /* Local buffer encoded in UTF-8 or ISOLatin */
+    xmlBufferPtr conv;      /* if encoder != NULL buffer for output */
+    int written;            /* total number of byte written */
+};
+
+/*
+ * Interfaces for input
  */
 
 xmlParserInputBufferPtr
@@ -72,6 +102,51 @@
 						 xmlInputOpenCallback open,
 						 xmlInputReadCallback read,
 						 xmlInputCloseCallback close);
+/*
+ * Interfaces for output
+ */
+xmlOutputBufferPtr
+	xmlAllocOutputBuffer		(xmlCharEncodingHandlerPtr encoder);
+
+xmlOutputBufferPtr
+	xmlOutputBufferCreateFilename	(const char *URI,
+					 xmlCharEncodingHandlerPtr encoder,
+					 int compression);
+
+xmlOutputBufferPtr
+	xmlOutputBufferCreateFile	(FILE *file,
+					 xmlCharEncodingHandlerPtr encoder);
+
+xmlOutputBufferPtr
+	xmlOutputBufferCreateFd		(int fd,
+					 xmlCharEncodingHandlerPtr encoder);
+
+xmlOutputBufferPtr
+	xmlOutputBufferCreateIO		(xmlOutputWriteCallback   iowrite,
+					 xmlOutputCloseCallback  ioclose,
+					 void *ioctx,
+					 xmlCharEncodingHandlerPtr encoder);
+
+int	xmlOutputBufferWrite		(xmlOutputBufferPtr out,
+					 int len,
+					 const char *buf);
+int	xmlOutputBufferWriteString	(xmlOutputBufferPtr out,
+					 const char *str);
+
+int	xmlOutputBufferFlush		(xmlOutputBufferPtr out);
+int	xmlOutputBufferClose		(xmlOutputBufferPtr out);
+
+int     xmlRegisterOutputCallbacks	(xmlOutputMatchCallback match,
+					 xmlOutputOpenCallback open,
+					 xmlOutputWriteCallback write,
+					 xmlOutputCloseCallback close);
+
+/*
+ * This save function is part of tree.h actually
+ */
+int		xmlSaveFileTo		(xmlOutputBuffer *buf,
+					 xmlDocPtr cur,
+					 const char *encoding);
 #ifdef __cplusplus
 }
 #endif
diff --git a/xmllint.c b/xmllint.c
index 24c17f7..dcd7161 100644
--- a/xmllint.c
+++ b/xmllint.c
@@ -68,6 +68,7 @@
 static int push = 0;
 static int noblanks = 0;
 static int testIO = 0;
+static char *encoding = NULL;
 
 extern int xmlDoValidityCheckingDefaultValue;
 extern int xmlGetWarningsDefaultValue;
@@ -499,6 +500,8 @@
 #endif
 	    if (compress)
 		xmlSaveFile("-", doc);
+	    else if (encoding != NULL)
+	        xmlSaveFileEnc("-", doc, encoding);
 	    else
 		xmlDocDump(stdout, doc);
 #ifdef LIBXML_DEBUG_ENABLED
@@ -531,6 +534,7 @@
     int i, count;
     int files = 0;
 
+    LIBXML_TEST_VERSION
     for (i = 1; i < argc ; i++) {
 #ifdef LIBXML_DEBUG_ENABLED
 	if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
@@ -593,6 +597,11 @@
 	         (!strcmp(argv[i], "--nowarning"))) {
 	    xmlGetWarningsDefaultValue = 0;
         }
+	else if ((!strcmp(argv[i], "-encode")) ||
+	         (!strcmp(argv[i], "--encode"))) {
+	    i++;
+	    encoding = argv[i];
+        }
 	else if ((!strcmp(argv[i], "-noblanks")) ||
 	         (!strcmp(argv[i], "--noblanks"))) {
 	     noblanks++;
@@ -613,6 +622,11 @@
 		argv[0]);
     }
     for (i = 1; i < argc ; i++) {
+	if ((!strcmp(argv[i], "-encode")) ||
+	         (!strcmp(argv[i], "--encode"))) {
+	    i++;
+	    continue;
+        }
 	if (argv[i][0] != '-') {
 	    if (repeat) {
 		for (count = 0;count < 100 * repeat;count++)
diff --git a/xmlversion.h.in b/xmlversion.h.in
index 5a62c27..b5edc09 100644
--- a/xmlversion.h.in
+++ b/xmlversion.h.in
@@ -9,8 +9,14 @@
 #ifndef __XML_VERSION_H__
 #define __XML_VERSION_H__
 
+/*
+ * use those to be sure nothing nasty will happen if
+ * your library and includes mismatch
+ */
+extern void xmlCheckVersion(int version);
 #define LIBXML_VERSION @LIBXML_VERSION_NUMBER@
 #define LIBXML_VERSION_STRING "@LIBXML_VERSION_NUMBER@"
+#define LIBXML_TEST_VERSION xmlCheckVersion(@LIBXML_VERSION_NUMBER@);
 
 /*
  * Whether the FTP support is configured in
diff --git a/xpath.c b/xpath.c
index a8867a4..19499b7 100644
--- a/xpath.c
+++ b/xpath.c
@@ -733,15 +733,19 @@
 xmlXPathObjectPtr
 xmlXPathNewNodeSetList(xmlNodeSetPtr val) {
     xmlXPathObjectPtr ret;
+    int i;
 
-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-    if (ret == NULL) {
-        fprintf(xmlXPathDebug, "xmlXPathNewFloat: out of memory\n");
-	return(NULL);
-    }
-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-    ret->type = XPATH_NODESET;
-    ret->nodesetval = val;
+    if (val == NULL)
+    	ret = NULL;
+    else if (val->nodeTab == NULL)
+	    ret = xmlXPathNewNodeSet(NULL);
+    else
+    	{
+	    ret = xmlXPathNewNodeSet(val->nodeTab[0]);
+	    for (i = 1; i < val->nodeNr; ++i)
+	    	xmlXPathNodeSetAdd(ret->nodesetval, val->nodeTab[i]);
+	    }
+
     return(ret);
 }
 
@@ -1541,7 +1545,11 @@
         return(ctxt->context->node->children);
     }
 
-    if (cur->children != NULL) return(cur->children);
+    if (cur->children != NULL)
+    	{
+    	if (cur->children->type != XML_ENTITY_DECL)
+		   	return(cur->children);
+    	}
     if (cur->next != NULL) return(cur->next);
     
     do {
@@ -3692,9 +3700,10 @@
 	    xmlXPathEvalFilterExpr(ctxt);
 	if (name != NULL)
 	    xmlFree(name);
-    }
+
     if (ctxt->context->nodelist != NULL)
 	valuePush(ctxt, xmlXPathNewNodeSetList(ctxt->context->nodelist));
+    } 
 }
 
 /**
@@ -3933,7 +3942,7 @@
     xmlXPathEvalEqualityExpr(ctxt);
     CHECK_ERROR;
     SKIP_BLANKS;
-    while ((CUR == 'a') && (NXT(1) == 'n') && (NXT(2) == 'n')) {
+    while ((CUR == 'a') && (NXT(1) == 'n') && (NXT(2) == 'd')) {
 	xmlXPathObjectPtr arg1, arg2;
 
         SKIP(3);
@@ -4028,7 +4037,7 @@
 void
 xmlXPathEvalPredicate(xmlXPathParserContextPtr ctxt) {
     const xmlChar *cur;
-    xmlXPathObjectPtr res;
+    xmlXPathObjectPtr res, listHolder = NULL;
     xmlNodeSetPtr newset = NULL;
     int i;
 
@@ -4049,20 +4058,42 @@
     } else {
         cur = ctxt->cur;
 	newset = xmlXPathNodeSetCreate(NULL);
+	
+	/*	Create a copy of the current node set because it is important:	*/	
+	listHolder = xmlXPathNewNodeSetList(ctxt->context->nodelist);
+		
         for (i = 0; i < ctxt->context->nodelist->nodeNr; i++) {
 	    ctxt->cur = cur;
 	    ctxt->context->node = ctxt->context->nodelist->nodeTab[i];
+
+		/*	This nodeset is useful for the loop but no, longer necessary this iteration:	*/
+		if (ctxt->context->nodelist != NULL)
+		    xmlXPathFreeNodeSet(ctxt->context->nodelist);
+
+		/*	This line was missed out:	*/
+		ctxt->context->nodelist = xmlXPathNodeSetCreate(ctxt->context->node);
+
 	    xmlXPathEvalExpr(ctxt);
 	    CHECK_ERROR;
 	    res = valuePop(ctxt);
 	    if (xmlXPathEvaluatePredicateResult(ctxt, res, i + 1))
-	        xmlXPathNodeSetAdd(newset,
-		                   ctxt->context->nodelist->nodeTab[i]);
+	    	{
+		    /*	Add the current node as the result has proven correct:	*/
+	        xmlXPathNodeSetAdd(newset, listHolder->nodesetval->nodeTab[i]);
+		    }
 	    if (res != NULL)
 	    xmlXPathFreeObject(res);
+	    
+	    /*	Copy the contents of the temporary list back to the node list for the next round:	*/
+        ctxt->context->nodelist = xmlXPathNewNodeSetList(listHolder->nodesetval)->nodesetval;
 	}
 	if (ctxt->context->nodelist != NULL)
 	    xmlXPathFreeNodeSet(ctxt->context->nodelist);
+	    
+	/*	Clean up after temporary variable holder:	*/    
+	if (listHolder != NULL)
+		xmlXPathFreeObject(listHolder);
+		
 	ctxt->context->nodelist = newset;
 	ctxt->context->node = NULL;
     }
@@ -4392,6 +4423,11 @@
 	while (CUR == '[') {
 	    xmlXPathEvalPredicate(ctxt);
 	}
+
+	while (CUR == '@') {
+		xmlXPathEvalBasis(ctxt);
+		ctxt->context->node = NULL;
+	}
     }
 #ifdef DEBUG_STEP
     fprintf(xmlXPathDebug, "Step : ");
@@ -4537,6 +4573,7 @@
 	res = xmlXPathNewNodeSetList(pctxt->context->nodelist);
     else
         res = NULL;
+        
     xmlXPathFreeParserContext(pctxt);
     return(res);
 }
diff --git a/xpath.h b/xpath.h
index 73e3f65..fc567fd 100644
--- a/xpath.h
+++ b/xpath.h
@@ -29,8 +29,8 @@
 typedef struct _xmlNodeSet xmlNodeSet;
 typedef xmlNodeSet *xmlNodeSetPtr;
 struct _xmlNodeSet {
-    int nodeNr;			/* # of node in the set */
-    int nodeMax;		/* allocated space */
+    int nodeNr;			/* number of nodes in the set */
+    int nodeMax;		/* size of the array as allocated */
     xmlNodePtr *nodeTab;	/* array of nodes in no particular order */
 };
 
@@ -41,6 +41,8 @@
  *   - boolean
  *   - number
  *   - string
+ *
+ * @@ XPointer will add more types !
  */
 
 #define XPATH_UNDEFINED	0