am 60fd9a36: (-s ours) DO NOT MERGE Fix for CVE-2011-3919

* commit '60fd9a3698956b22cb34a7553cf38cf679f473a6':
  DO NOT MERGE Fix for CVE-2011-3919
diff --git a/Copyright b/Copyright
new file mode 100644
index 0000000..417e955
--- /dev/null
+++ b/Copyright
@@ -0,0 +1,27 @@
+Except where otherwise noted in the source code (e.g. the files hash.c,
+list.c and the trio files, which are covered by a similar licence but
+with different Copyright notices) all the files are:
+
+ Copyright (C) 1998-2003 Daniel Veillard.  All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is fur-
+nished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+DANIEL VEILLARD BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Daniel Veillard shall not
+be used in advertising or otherwise to promote the sale, use or other deal-
+ings in this Software without prior written authorization from him.
+
diff --git a/HTMLparser.c b/HTMLparser.c
index 24b0fc0..1a4d80d 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -59,7 +59,7 @@
 
 /************************************************************************
  *									*
- * 		Some factorized error routines				*
+ *		Some factorized error routines				*
  *									*
  ************************************************************************/
 
@@ -147,7 +147,7 @@
 
 /************************************************************************
  *									*
- * 		Parser stacks related functions and macros		*
+ *	Parser stacks related functions and macros		*
  *									*
  ************************************************************************/
 
@@ -163,6 +163,10 @@
 static int
 htmlnamePush(htmlParserCtxtPtr ctxt, const xmlChar * value)
 {
+    if ((ctxt->html < 3) && (xmlStrEqual(value, BAD_CAST "head")))
+        ctxt->html = 3;
+    if ((ctxt->html < 10) && (xmlStrEqual(value, BAD_CAST "body")))
+        ctxt->html = 10;
     if (ctxt->nameNr >= ctxt->nameMax) {
         ctxt->nameMax *= 2;
         ctxt->nameTab = (const xmlChar * *)
@@ -205,6 +209,59 @@
     return (ret);
 }
 
+/**
+ * htmlNodeInfoPush:
+ * @ctxt:  an HTML parser context
+ * @value:  the node info
+ *
+ * Pushes a new element name on top of the node info stack
+ *
+ * Returns 0 in case of error, the index in the stack otherwise
+ */
+static int
+htmlNodeInfoPush(htmlParserCtxtPtr ctxt, htmlParserNodeInfo *value)
+{
+    if (ctxt->nodeInfoNr >= ctxt->nodeInfoMax) {
+        if (ctxt->nodeInfoMax == 0)
+                ctxt->nodeInfoMax = 5;
+        ctxt->nodeInfoMax *= 2;
+        ctxt->nodeInfoTab = (htmlParserNodeInfo *)
+                         xmlRealloc((htmlParserNodeInfo *)ctxt->nodeInfoTab,
+                                    ctxt->nodeInfoMax *
+                                    sizeof(ctxt->nodeInfoTab[0]));
+        if (ctxt->nodeInfoTab == NULL) {
+            htmlErrMemory(ctxt, NULL);
+            return (0);
+        }
+    }
+    ctxt->nodeInfoTab[ctxt->nodeInfoNr] = *value;
+    ctxt->nodeInfo = &ctxt->nodeInfoTab[ctxt->nodeInfoNr];
+    return (ctxt->nodeInfoNr++);
+}
+
+/**
+ * htmlNodeInfoPop:
+ * @ctxt:  an HTML parser context
+ *
+ * Pops the top element name from the node info stack
+ *
+ * Returns 0 in case of error, the pointer to NodeInfo otherwise
+ */
+static htmlParserNodeInfo *
+htmlNodeInfoPop(htmlParserCtxtPtr ctxt)
+{
+    if (ctxt->nodeInfoNr <= 0)
+        return (NULL);
+    ctxt->nodeInfoNr--;
+    if (ctxt->nodeInfoNr < 0)
+        return (NULL);
+    if (ctxt->nodeInfoNr > 0)
+        ctxt->nodeInfo = &ctxt->nodeInfoTab[ctxt->nodeInfoNr - 1];
+    else
+        ctxt->nodeInfo = NULL;
+    return &ctxt->nodeInfoTab[ctxt->nodeInfoNr];
+}
+
 /*
  * Macros for accessing the content. Those should be used only by the parser,
  * and not exported.
@@ -263,8 +320,6 @@
 #define NEXT xmlNextChar(ctxt)
 
 #define RAW (ctxt->token ? -1 : (*ctxt->input->cur))
-#define NXT(val) ctxt->input->cur[(val)]
-#define CUR_PTR ctxt->input->cur
 
 
 #define NEXTL(l) do {							\
@@ -273,7 +328,7 @@
     } else ctxt->input->col++;						\
     ctxt->token = 0; ctxt->input->cur += l; ctxt->nbChars++;		\
   } while (0)
-    
+
 /************
     \
     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);	\
@@ -288,6 +343,58 @@
     else i += xmlCopyChar(l,&b[i],v)
 
 /**
+ * htmlFindEncoding:
+ * @the HTML parser context
+ *
+ * Ty to find and encoding in the current data available in the input
+ * buffer this is needed to try to switch to the proper encoding when
+ * one face a character error.
+ * That's an heuristic, since it's operating outside of parsing it could
+ * try to use a meta which had been commented out, that's the reason it
+ * should only be used in case of error, not as a default.
+ *
+ * Returns an encoding string or NULL if not found, the string need to
+ *   be freed
+ */
+static xmlChar *
+htmlFindEncoding(xmlParserCtxtPtr ctxt) {
+    const xmlChar *start, *cur, *end;
+
+    if ((ctxt == NULL) || (ctxt->input == NULL) ||
+        (ctxt->input->encoding != NULL) || (ctxt->input->buf == NULL) ||
+        (ctxt->input->buf->encoder != NULL))
+        return(NULL);
+    if ((ctxt->input->cur == NULL) || (ctxt->input->end == NULL))
+        return(NULL);
+
+    start = ctxt->input->cur;
+    end = ctxt->input->end;
+    /* we also expect the input buffer to be zero terminated */
+    if (*end != 0)
+        return(NULL);
+
+    cur = xmlStrcasestr(start, BAD_CAST "HTTP-EQUIV");
+    if (cur == NULL)
+        return(NULL);
+    cur = xmlStrcasestr(cur, BAD_CAST  "CONTENT");
+    if (cur == NULL)
+        return(NULL);
+    cur = xmlStrcasestr(cur, BAD_CAST  "CHARSET=");
+    if (cur == NULL)
+        return(NULL);
+    cur += 8;
+    start = cur;
+    while (((*cur >= 'A') && (*cur <= 'Z')) ||
+           ((*cur >= 'a') && (*cur <= 'z')) ||
+           ((*cur >= '0') && (*cur <= '9')) ||
+           (*cur == '-') || (*cur == '_') || (*cur == ':') || (*cur == '/'))
+           cur++;
+    if (cur == start)
+        return(NULL);
+    return(xmlStrndup(start, cur - start));
+}
+
+/**
  * htmlCurrentChar:
  * @ctxt:  the HTML parser context
  * @len:  pointer to the length of the char read
@@ -309,7 +416,7 @@
     if (ctxt->token != 0) {
 	*len = 0;
 	return(ctxt->token);
-    }	
+    }
     if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
 	/*
 	 * We are supposed to handle UTF8, check it's valid
@@ -318,7 +425,7 @@
 	 * UCS-4 range (hex.)           UTF-8 octet sequence (binary)
 	 * 0000 0000-0000 007F   0xxxxxxx
 	 * 0000 0080-0000 07FF   110xxxxx 10xxxxxx
-	 * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx 
+	 * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx
 	 *
 	 * Check for the 0x110000 limit too
 	 */
@@ -328,19 +435,25 @@
 
 	c = *cur;
 	if (c & 0x80) {
-	    if (cur[1] == 0)
+	    if (cur[1] == 0) {
 		xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+                cur = ctxt->input->cur;
+            }
 	    if ((cur[1] & 0xc0) != 0x80)
 		goto encoding_error;
 	    if ((c & 0xe0) == 0xe0) {
 
-		if (cur[2] == 0)
+		if (cur[2] == 0) {
 		    xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+                    cur = ctxt->input->cur;
+                }
 		if ((cur[2] & 0xc0) != 0x80)
 		    goto encoding_error;
 		if ((c & 0xf0) == 0xf0) {
-		    if (cur[3] == 0)
+		    if (cur[3] == 0) {
 			xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+                        cur = ctxt->input->cur;
+                    }
 		    if (((c & 0xf8) != 0xf0) ||
 			((cur[3] & 0xc0) != 0x80))
 			goto encoding_error;
@@ -366,9 +479,16 @@
 	    if (!IS_CHAR(val)) {
 	        htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
 				"Char 0x%X out of allowed range\n", val);
-	    }    
+	    }
 	    return(val);
 	} else {
+            if ((*ctxt->input->cur == 0) &&
+                (ctxt->input->cur < ctxt->input->end)) {
+                    htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
+				"Char 0x%X out of allowed range\n", 0);
+                *len = 1;
+                return(' ');
+            }
 	    /* 1-byte code */
 	    *len = 1;
 	    return((int) *ctxt->input->cur);
@@ -386,8 +506,28 @@
     /*
      * Humm this is bad, do an automatic flow conversion
      */
-    xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1);
-    ctxt->charset = XML_CHAR_ENCODING_UTF8;
+    {
+        xmlChar * guess;
+        xmlCharEncodingHandlerPtr handler;
+
+        guess = htmlFindEncoding(ctxt);
+        if (guess == NULL) {
+            xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1);
+        } else {
+            if (ctxt->input->encoding != NULL)
+                xmlFree((xmlChar *) ctxt->input->encoding);
+            ctxt->input->encoding = guess;
+            handler = xmlFindCharEncodingHandler((const char *) guess);
+            if (handler != NULL) {
+                xmlSwitchToEncoding(ctxt, handler);
+            } else {
+                htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING,
+                             "Unsupported encoding %s", guess, NULL);
+            }
+        }
+        ctxt->charset = XML_CHAR_ENCODING_UTF8;
+    }
+
     return(xmlCurrentChar(ctxt, len));
 
 encoding_error:
@@ -413,7 +553,7 @@
 		     BAD_CAST buffer, NULL);
     }
 
-    ctxt->charset = XML_CHAR_ENCODING_8859_1; 
+    ctxt->charset = XML_CHAR_ENCODING_8859_1;
     *len = 1;
     return((int) *ctxt->input->cur);
 }
@@ -453,7 +593,7 @@
 
 /************************************************************************
  *									*
- * 		The list of HTML elements and their properties		*
+ *	The list of HTML elements and their properties		*
  *									*
  ************************************************************************/
 
@@ -478,9 +618,9 @@
 #define NB_PHRASE 10
 #define SPECIAL "a", "img", "applet", "embed", "object", "font", "basefont", "br", "script", "map", "q", "sub", "sup", "span", "bdo", "iframe"
 #define NB_SPECIAL 16
-#define INLINE PCDATA FONTSTYLE PHRASE SPECIAL FORMCTRL
+#define INLINE FONTSTYLE, PHRASE, SPECIAL, FORMCTRL
 #define NB_INLINE NB_PCDATA + NB_FONTSTYLE + NB_PHRASE + NB_SPECIAL + NB_FORMCTRL
-#define BLOCK HEADING, LIST "pre", "p", "dl", "div", "center", "noscript", "noframes", "blockquote", "form", "isindex", "hr", "table", "fieldset", "address"
+#define BLOCK HEADING, LIST, "pre", "p", "dl", "div", "center", "noscript", "noframes", "blockquote", "form", "isindex", "hr", "table", "fieldset", "address"
 #define NB_BLOCK NB_HEADING + NB_LIST + 14
 #define FORMCTRL "input", "select", "textarea", "label", "button"
 #define NB_FORMCTRL 5
@@ -606,7 +746,7 @@
 static const char* const select_content[] = { "optgroup", "option", NULL } ;
 static const char* const select_attrs[] = { ATTRS, "name", "size", "multiple", "disabled", "tabindex", "onfocus", "onblur", "onchange", NULL } ;
 static const char* const style_attrs[] = { I18N, "media", "title", NULL } ;
-static const char* const table_attrs[] = { ATTRS "summary", "width", "border", "frame", "rules", "cellspacing", "cellpadding", "datapagesize", NULL } ;
+static const char* const table_attrs[] = { ATTRS, "summary", "width", "border", "frame", "rules", "cellspacing", "cellpadding", "datapagesize", NULL } ;
 static const char* const table_depr[] = { "align", "bgcolor", NULL } ;
 static const char* const table_contents[] = { "caption", "col", "colgroup", "thead", "tfoot", "tbody", "tr", NULL} ;
 static const char* const tr_elt[] = { "tr", NULL } ;
@@ -938,7 +1078,7 @@
 		"listing", "xmp", NULL,
 "ol",		"p", "head", "ul", NULL,
 "menu",		"p", "head", "ul", NULL,
-"p",		"p", "head", "h1", "h2", "h3", "h4", "h5", "h6", NULL,
+"p",		"p", "head", "h1", "h2", "h3", "h4", "h5", "h6", FONTSTYLE, NULL,
 "div",		"p", "head", NULL,
 "noscript",	"p", "head", NULL,
 "center",	"font", "b", "i", "p", "head", NULL,
@@ -949,7 +1089,7 @@
 "table",	"p", "head", "h1", "h2", "h3", "h4", "h5", "h6", "pre",
 		"listing", "xmp", "a", NULL,
 "th",		"th", "td", "p", "span", "font", "a", "b", "i", "u", NULL,
-"td",		"th", "td", "p", "span", "font", "a", "b", "i", "u", NULL,      
+"td",		"th", "td", "p", "span", "font", "a", "b", "i", "u", NULL,
 "tr",		"th", "td", "tr", "caption", "col", "colgroup", "p", NULL,
 "thead",	"caption", "col", "colgroup", NULL,
 "tfoot",	"th", "td", "tr", "caption", "col", "colgroup", "thead",
@@ -1008,7 +1148,7 @@
  * elements the parser can decide how to handle extra endtags.
  * Endtags are only allowed to close elements with lower or equal
  * priority.
- */ 
+ */
 
 typedef struct {
     const char *name;
@@ -1035,7 +1175,7 @@
 
 /************************************************************************
  *									*
- * 		functions to handle HTML specific data			*
+ *	functions to handle HTML specific data			*
  *									*
  ************************************************************************/
 
@@ -1085,7 +1225,7 @@
 /**
  * htmlGetEndPriority:
  * @name: The name of the element to look up the priority for.
- * 
+ *
  * Return value: The "endtag" priority.
  **/
 static int
@@ -1164,7 +1304,7 @@
          * A missplaced endtag can only close elements with lower
          * or equal priority, so if we find an element with higher
          * priority before we find an element with
-         * matching name, we just ignore this endtag 
+         * matching name, we just ignore this endtag
          */
         if (htmlGetEndPriority(ctxt->nameTab[i]) > priority)
             return;
@@ -1215,7 +1355,7 @@
  * called when a new tag has been detected and generates the
  * appropriates closes if possible/needed.
  * If newtag is NULL this mean we are at the end of the resource
- * and we should check 
+ * and we should check
  */
 static void
 htmlAutoClose(htmlParserCtxtPtr ctxt, const xmlChar * newtag)
@@ -1303,6 +1443,10 @@
  */
 static void
 htmlCheckImplied(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
+    int i;
+
+    if (ctxt->options & HTML_PARSE_NOIMPLIED)
+        return;
     if (!htmlOmittedDefaultValue)
 	return;
     if (xmlStrEqual(newtag, BAD_CAST"html"))
@@ -1314,24 +1458,31 @@
     }
     if ((xmlStrEqual(newtag, BAD_CAST"body")) || (xmlStrEqual(newtag, BAD_CAST"head")))
         return;
-    if ((ctxt->nameNr <= 1) && 
+    if ((ctxt->nameNr <= 1) &&
         ((xmlStrEqual(newtag, BAD_CAST"script")) ||
 	 (xmlStrEqual(newtag, BAD_CAST"style")) ||
 	 (xmlStrEqual(newtag, BAD_CAST"meta")) ||
 	 (xmlStrEqual(newtag, BAD_CAST"link")) ||
 	 (xmlStrEqual(newtag, BAD_CAST"title")) ||
 	 (xmlStrEqual(newtag, BAD_CAST"base")))) {
-	    /* 
-	     * dropped OBJECT ... i you put it first BODY will be
-	     * assumed !
-	     */
-	    htmlnamePush(ctxt, BAD_CAST"head");
-	    if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
-		ctxt->sax->startElement(ctxt->userData, BAD_CAST"head", NULL);
+        if (ctxt->html >= 3) {
+            /* we already saw or generated an <head> before */
+            return;
+        }
+        /*
+         * dropped OBJECT ... i you put it first BODY will be
+         * assumed !
+         */
+        htmlnamePush(ctxt, BAD_CAST"head");
+        if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
+            ctxt->sax->startElement(ctxt->userData, BAD_CAST"head", NULL);
     } else if ((!xmlStrEqual(newtag, BAD_CAST"noframes")) &&
 	       (!xmlStrEqual(newtag, BAD_CAST"frame")) &&
 	       (!xmlStrEqual(newtag, BAD_CAST"frameset"))) {
-	int i;
+        if (ctxt->html >= 10) {
+            /* we already saw or generated a <body> before */
+            return;
+        }
 	for (i = 0;i < ctxt->nameNr;i++) {
 	    if (xmlStrEqual(ctxt->nameTab[i], BAD_CAST"body")) {
 		return;
@@ -1340,7 +1491,7 @@
 		return;
 	    }
 	}
-	    
+
 	htmlnamePush(ctxt, BAD_CAST"body");
 	if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
 	    ctxt->sax->startElement(ctxt->userData, BAD_CAST"body", NULL);
@@ -1402,12 +1553,12 @@
     unsigned int i;
 
     if (name == NULL)
-       	return(0);
+      return(0);
     /*
      * all script attributes start with 'on'
      */
     if ((name[0] != 'o') || (name[1] != 'n'))
-       	return(0);
+      return(0);
     for (i = 0;
 	 i < sizeof(htmlScriptAttributes)/sizeof(htmlScriptAttributes[0]);
 	 i++) {
@@ -1419,7 +1570,7 @@
 
 /************************************************************************
  *									*
- * 		The list of HTML predefined entities			*
+ *	The list of HTML predefined entities			*
  *									*
  ************************************************************************/
 
@@ -1833,7 +1984,7 @@
 
 	if (inend - in < trailing) {
 	    break;
-	} 
+	}
 
 	for ( ; trailing; trailing--) {
 	    if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))
@@ -2023,7 +2174,7 @@
  *									*
  ************************************************************************/
 /*
- * all tags allowing pc data from the html 4.01 loose dtd 
+ * all tags allowing pc data from the html 4.01 loose dtd
  * NOTE: it might be more apropriate to integrate this information
  * into the html40ElementTable array but I don't want to risk any
  * binary incomptibility
@@ -2083,7 +2234,7 @@
     if (lastChild == NULL) {
         if ((ctxt->node->type != XML_ELEMENT_NODE) &&
             (ctxt->node->content != NULL)) return(0);
-	/* keep ws in constructs like ...<b> </b>... 
+	/* keep ws in constructs like ...<b> </b>...
 	   for all tags "b" allowing PCDATA */
 	for ( i = 0; i < sizeof(allowPCData)/sizeof(allowPCData[0]); i++ ) {
 	    if ( xmlStrEqual(ctxt->name, BAD_CAST allowPCData[i]) ) {
@@ -2093,7 +2244,7 @@
     } else if (xmlNodeIsText(lastChild)) {
         return(0);
     } else {
-	/* keep ws in constructs like <p><b>xy</b> <i>z</i><p> 
+	/* keep ws in constructs like <p><b>xy</b> <i>z</i><p>
 	   for all tags "p" allowing PCDATA */
 	for ( i = 0; i < sizeof(allowPCData)/sizeof(allowPCData[0]); i++ ) {
 	    if ( xmlStrEqual(lastChild->name, BAD_CAST allowPCData[i]) ) {
@@ -2133,7 +2284,7 @@
     cur->intSubset = NULL;
     cur->doc = cur;
     cur->name = NULL;
-    cur->children = NULL; 
+    cur->children = NULL;
     cur->extSubset = NULL;
     cur->oldNs = NULL;
     cur->encoding = NULL;
@@ -2201,18 +2352,19 @@
     xmlChar loc[HTML_PARSER_BUFFER_SIZE];
 
     if (!IS_ASCII_LETTER(CUR) && (CUR != '_') &&
-        (CUR != ':')) return(NULL);
+        (CUR != ':') && (CUR != '.')) return(NULL);
 
     while ((i < HTML_PARSER_BUFFER_SIZE) &&
            ((IS_ASCII_LETTER(CUR)) || (IS_ASCII_DIGIT(CUR)) ||
-	   (CUR == ':') || (CUR == '-') || (CUR == '_'))) {
+	   (CUR == ':') || (CUR == '-') || (CUR == '_') ||
+           (CUR == '.'))) {
 	if ((CUR >= 'A') && (CUR <= 'Z')) loc[i] = CUR + 0x20;
         else loc[i] = CUR;
 	i++;
-	
+
 	NEXT;
     }
-    
+
     return(xmlDictLookup(ctxt->dict, loc, i));
 }
 
@@ -2235,7 +2387,7 @@
 
     if (!IS_ASCII_LETTER(NXT(1)) && (NXT(1) != '_') &&
         (NXT(1) != ':')) return(NULL);
- 
+
     while ((i < HTML_PARSER_BUFFER_SIZE) &&
            ((IS_ASCII_LETTER(NXT(1+i))) || (IS_ASCII_DIGIT(NXT(1+i))) ||
 	   (NXT(1+i) == ':') || (NXT(1+i) == '-') || (NXT(1+i) == '_'))) {
@@ -2243,7 +2395,7 @@
         else loc[i] = NXT(1+i);
 	i++;
     }
-    
+
     return(xmlDictLookup(ctxt->dict, loc, i));
 }
 
@@ -2311,7 +2463,7 @@
     while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
 	   ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
             (c == '.') || (c == '-') ||
-	    (c == '_') || (c == ':') || 
+	    (c == '_') || (c == ':') ||
 	    (IS_COMBINING(c)) ||
 	    (IS_EXTENDER(c)))) {
 	if (count++ > 100) {
@@ -2330,7 +2482,7 @@
  * htmlParseHTMLAttribute:
  * @ctxt:  an HTML parser context
  * @stop:  a char stop value
- * 
+ *
  * parse an HTML attribute value till the stop (quote), if
  * stop is 0 then it stops at the first space
  *
@@ -2375,13 +2527,13 @@
 		        { *out++  =((c >>  6) & 0x1F) | 0xC0;  bits=  0; }
 		else if (c < 0x10000)
 		        { *out++  =((c >> 12) & 0x0F) | 0xE0;  bits=  6; }
-		else                 
+		else
 		        { *out++  =((c >> 18) & 0x07) | 0xF0;  bits= 12; }
-	 
+
 		for ( ; bits >= 0; bits-= 6) {
 		    *out++  = ((c >> bits) & 0x3F) | 0x80;
 		}
-		
+
 		if (out - buffer > buffer_size - 100) {
 			int indx = out - buffer;
 
@@ -2427,9 +2579,9 @@
 			{ *out++  =((c >>  6) & 0x1F) | 0xC0;  bits=  0; }
 		    else if (c < 0x10000)
 			{ *out++  =((c >> 12) & 0x0F) | 0xE0;  bits=  6; }
-		    else                 
+		    else
 			{ *out++  =((c >> 18) & 0x07) | 0xF0;  bits= 12; }
-	     
+
 		    for ( ; bits >= 0; bits-= 6) {
 			*out++  = ((c >> bits) & 0x3F) | 0x80;
 		    }
@@ -2452,16 +2604,16 @@
 		    { *out++  =((c >>  6) & 0x1F) | 0xC0;  bits=  0; }
 	    else if (c < 0x10000)
 		    { *out++  =((c >> 12) & 0x0F) | 0xE0;  bits=  6; }
-	    else                 
+	    else
 		    { *out++  =((c >> 18) & 0x07) | 0xF0;  bits= 12; }
-     
+
 	    for ( ; bits >= 0; bits-= 6) {
 		*out++  = ((c >> bits) & 0x3F) | 0x80;
 	    }
 	    NEXT;
 	}
     }
-    *out++ = 0;
+    *out = 0;
     return(buffer);
 }
 
@@ -2522,7 +2674,7 @@
  * parse a value for an attribute
  * Note: the parser won't do substitution of entities here, this
  * will be handled later in xmlStringGetNodeList, unless it was
- * asked for ctxt->replaceEntities != 0 
+ * asked for ctxt->replaceEntities != 0
  *
  * Returns the AttValue parsed or NULL.
  */
@@ -2563,7 +2715,7 @@
 /**
  * htmlParseSystemLiteral:
  * @ctxt:  an HTML parser context
- * 
+ *
  * parse an HTML Literal
  *
  * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
@@ -2604,7 +2756,7 @@
 	htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_STARTED,
 	             " or ' expected\n", NULL, NULL);
     }
-    
+
     return(ret);
 }
 
@@ -2653,7 +2805,7 @@
 	htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_STARTED,
 	             "PubidLiteral \" or ' expected\n", NULL, NULL);
     }
-    
+
     return(ret);
 }
 
@@ -2700,8 +2852,8 @@
              * CDATA.
              */
             if (ctxt->recovery) {
-                if (xmlStrncasecmp(ctxt->name, ctxt->input->cur+2, 
-				   xmlStrlen(ctxt->name)) == 0) 
+                if (xmlStrncasecmp(ctxt->name, ctxt->input->cur+2,
+				   xmlStrlen(ctxt->name)) == 0)
                 {
                     break; /* while */
                 } else {
@@ -2711,7 +2863,7 @@
 		}
             } else {
                 if (((NXT(2) >= 'A') && (NXT(2) <= 'Z')) ||
-                    ((NXT(2) >= 'a') && (NXT(2) <= 'z'))) 
+                    ((NXT(2) >= 'a') && (NXT(2) <= 'z')))
                 {
                     break; /* while */
                 }
@@ -2735,9 +2887,11 @@
     }
 
     if ((!(IS_CHAR_CH(cur))) && (!((cur == 0) && (ctxt->progressive)))) {
-	htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
-	                "Invalid char in CDATA 0x%X\n", cur);
-	NEXT;
+        htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
+                    "Invalid char in CDATA 0x%X\n", cur);
+        if (ctxt->input->cur < ctxt->input->end) {
+            NEXT;
+        }
     }
 
     if ((nbchar != 0) && (ctxt->sax != NULL) && (!ctxt->disableSAX)) {
@@ -2773,7 +2927,7 @@
     SHRINK;
     cur = CUR_CHAR(l);
     while (((cur != '<') || (ctxt->token == '<')) &&
-           ((cur != '&') || (ctxt->token == '&')) && 
+           ((cur != '&') || (ctxt->token == '&')) &&
 	   (cur != 0)) {
 	if (!(IS_CHAR(cur))) {
 	    htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
@@ -2999,7 +3153,7 @@
 	    }
 	    xmlFree(buf);
 	} else {
-	    htmlParseErr(ctxt, XML_ERR_PI_NOT_STARTED, 
+	    htmlParseErr(ctxt, XML_ERR_PI_NOT_STARTED,
                          "PI is not started correctly", NULL, NULL);
 	}
 	ctxt->instate = state;
@@ -3115,7 +3269,7 @@
         ((NXT(2) == 'x') || NXT(2) == 'X')) {
 	SKIP(3);
 	while (CUR != ';') {
-	    if ((CUR >= '0') && (CUR <= '9')) 
+	    if ((CUR >= '0') && (CUR <= '9'))
 	        val = val * 16 + (CUR - '0');
 	    else if ((CUR >= 'a') && (CUR <= 'f'))
 	        val = val * 16 + (CUR - 'a') + 10;
@@ -3123,7 +3277,7 @@
 	        val = val * 16 + (CUR - 'A') + 10;
 	    else {
 	        htmlParseErr(ctxt, XML_ERR_INVALID_HEX_CHARREF,
-		             "htmlParseCharRef: missing semicolumn\n",
+		             "htmlParseCharRef: missing semicolon\n",
 			     NULL, NULL);
 		break;
 	    }
@@ -3134,11 +3288,11 @@
     } else if  ((CUR == '&') && (NXT(1) == '#')) {
 	SKIP(2);
 	while (CUR != ';') {
-	    if ((CUR >= '0') && (CUR <= '9')) 
+	    if ((CUR >= '0') && (CUR <= '9'))
 	        val = val * 10 + (CUR - '0');
 	    else {
 	        htmlParseErr(ctxt, XML_ERR_INVALID_DEC_CHARREF,
-		             "htmlParseCharRef: missing semicolumn\n",
+		             "htmlParseCharRef: missing semicolon\n",
 			     NULL, NULL);
 		break;
 	    }
@@ -3170,7 +3324,7 @@
  *
  * parse a DOCTYPE declaration
  *
- * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? 
+ * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
  *                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
  */
 
@@ -3274,11 +3428,6 @@
         NEXT;
 	SKIP_BLANKS;
 	val = htmlParseAttValue(ctxt);
-    } else if (htmlIsBooleanAttr(name)) {
-        /*
-	 * assume a minimized attribute
-	 */
-	val = xmlStrdup(name);
     }
 
     *value = val;
@@ -3299,10 +3448,11 @@
 htmlCheckEncoding(htmlParserCtxtPtr ctxt, const xmlChar *attvalue) {
     const xmlChar *encoding;
 
-    if ((ctxt == NULL) || (attvalue == NULL))
+    if ((ctxt == NULL) || (attvalue == NULL) ||
+        (ctxt->options & HTML_PARSE_IGNORE_ENC))
 	return;
 
-    /* do not change encoding */	
+    /* do not change encoding */
     if (ctxt->input->encoding != NULL)
         return;
 
@@ -3329,7 +3479,7 @@
 	 * registered set of known encodings
 	 */
 	if (enc != XML_CHAR_ENCODING_ERROR) {
-	    if (((enc == XML_CHAR_ENCODING_UTF16LE) || 
+	    if (((enc == XML_CHAR_ENCODING_UTF16LE) ||
 	         (enc == XML_CHAR_ENCODING_UTF16BE) ||
 		 (enc == XML_CHAR_ENCODING_UCS4LE) ||
 		 (enc == XML_CHAR_ENCODING_UCS4BE)) &&
@@ -3351,7 +3501,9 @@
 		xmlSwitchToEncoding(ctxt, handler);
 		ctxt->charset = XML_CHAR_ENCODING_UTF8;
 	    } else {
-		ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
+		htmlParseErr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
+		             "htmlCheckEncoding: unknown encoding %s\n",
+			     encoding, NULL);
 	    }
 	}
 
@@ -3377,6 +3529,8 @@
 	    }
 	    ctxt->input->base =
 	    ctxt->input->cur = ctxt->input->buf->buffer->content;
+            ctxt->input->end =
+                          &ctxt->input->base[ctxt->input->buf->buffer->use];
 	}
     }
 }
@@ -3417,7 +3571,7 @@
 /**
  * htmlParseStartTag:
  * @ctxt:  an HTML parser context
- * 
+ *
  * parse a start of tag either for rule element or
  * EmptyElement. In both case we don't parse the tag closing chars.
  *
@@ -3446,6 +3600,8 @@
     int i;
     int discardtag = 0;
 
+    if (ctxt->instate == XML_PARSER_EOF)
+        return(-1);
     if ((ctxt == NULL) || (ctxt->input == NULL)) {
 	htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
 		     "htmlParseStartTag: context error\n", NULL, NULL);
@@ -3464,7 +3620,8 @@
 	             "htmlParseStartTag: invalid element name\n",
 		     NULL, NULL);
 	/* Dump the bogus tag like browsers do */
-	while ((IS_CHAR_CH(CUR)) && (CUR != '>'))
+	while ((IS_CHAR_CH(CUR)) && (CUR != '>') &&
+               (ctxt->instate != XML_PARSER_EOF))
 	    NEXT;
         return -1;
     }
@@ -3492,7 +3649,7 @@
 	discardtag = 1;
 	ctxt->depth++;
     }
-    if ((ctxt->nameNr != 1) && 
+    if ((ctxt->nameNr != 1) &&
 	(xmlStrEqual(name, BAD_CAST"head"))) {
 	htmlParseErr(ctxt, XML_HTML_STRUCURE_ERROR,
 	             "htmlParseStartTag: misplaced <head> tag\n",
@@ -3520,7 +3677,7 @@
      */
     SKIP_BLANKS;
     while ((IS_CHAR_CH(CUR)) &&
-           (CUR != '>') && 
+           (CUR != '>') &&
 	   ((CUR != '/') || (NXT(1) != '>'))) {
 	long cons = ctxt->nbChars;
 
@@ -3744,7 +3901,7 @@
 /**
  * htmlParseReference:
  * @ctxt:  an HTML parser context
- * 
+ *
  * parse and handle entity references in content,
  * this will end-up in a call to character() since this is either a
  * CharRef, or a predefined entity.
@@ -3768,7 +3925,7 @@
         else if (c <   0x800) { out[i++]=((c >>  6) & 0x1F) | 0xC0;  bits=  0; }
         else if (c < 0x10000) { out[i++]=((c >> 12) & 0x0F) | 0xE0;  bits=  6; }
         else                  { out[i++]=((c >> 18) & 0x07) | 0xF0;  bits= 12; }
- 
+
         for ( ; bits >= 0; bits-= 6) {
             out[i++]= ((c >> bits) & 0x3F) | 0x80;
         }
@@ -3803,9 +3960,9 @@
 	            { out[i++]=((c >>  6) & 0x1F) | 0xC0;  bits=  0; }
 	    else if (c < 0x10000)
 	            { out[i++]=((c >> 12) & 0x0F) | 0xE0;  bits=  6; }
-	    else                 
+	    else
 	            { out[i++]=((c >> 18) & 0x07) | 0xF0;  bits= 12; }
-     
+
 	    for ( ; bits >= 0; bits-= 6) {
 		out[i++]= ((c >> bits) & 0x3F) | 0x80;
 	    }
@@ -3823,6 +3980,7 @@
  * @ctxt:  an HTML parser context
  *
  * Parse a content: comment, sub-element, reference or text.
+ * Kept for compatibility with old code
  */
 
 static void
@@ -3837,6 +3995,10 @@
 	long cons = ctxt->nbChars;
 
         GROW;
+
+        if (ctxt->instate == XML_PARSER_EOF)
+            break;
+
 	/*
 	 * Our tag or one of it's parent or children is ending.
 	 */
@@ -3859,7 +4021,7 @@
 			 "htmlParseStartTag: invalid element name\n",
 			 NULL, NULL);
 	        /* Dump the bogus tag like browsers do */
- 	        while ((IS_CHAR_CH(CUR)) && (CUR != '>'))
+        while ((IS_CHAR_CH(CUR)) && (CUR != '>'))
 	            NEXT;
 
 	        if (currentNode != NULL)
@@ -3872,7 +4034,7 @@
 	            htmlAutoClose(ctxt, name);
 	            continue;
 	        }
-	    }	  
+	    }
 	}
 
 	/*
@@ -3931,7 +4093,7 @@
 
 	    /*
 	     * Fourth case : a reference. If if has not been resolved,
-	     *    parsing returns it's Name, create the node 
+	     *    parsing returns it's Name, create the node
 	     */
 	    else if (CUR == '&') {
 		htmlParseReference(ctxt);
@@ -3967,23 +4129,11 @@
 }
 
 /**
- * htmlParseContent:
- * @ctxt:  an HTML parser context
- *
- * Parse a content: comment, sub-element, reference or text.
- */
-
-void
-__htmlParseContent(void *ctxt) {
-    if (ctxt != NULL)
-	htmlParseContent((htmlParserCtxtPtr) ctxt);
-}
-
-/**
  * htmlParseElement:
  * @ctxt:  an HTML parser context
  *
  * parse an HTML element, this is highly recursive
+ * this is kept for compatibility with previous code versions
  *
  * [39] element ::= EmptyElemTag | STag content ETag
  *
@@ -4005,6 +4155,10 @@
 		     "htmlParseElement: context error\n", NULL, NULL);
 	return;
     }
+
+    if (ctxt->instate == XML_PARSER_EOF)
+        return;
+
     /* Capture start position */
     if (ctxt->record_info) {
         node_info.begin_pos = ctxt->input->consumed +
@@ -4049,10 +4203,10 @@
 	/*
 	 * end of parsing of this node.
 	 */
-	if (xmlStrEqual(name, ctxt->name)) { 
+	if (xmlStrEqual(name, ctxt->name)) {
 	    nodePop(ctxt);
 	    htmlnamePop(ctxt);
-	}    
+	}
 
 	/*
 	 * Capture end position and add node
@@ -4086,8 +4240,8 @@
 	oldptr = ctxt->input->cur;
 	htmlParseContent(ctxt);
 	if (oldptr==ctxt->input->cur) break;
-	if (ctxt->nameNr < depth) break; 
-    }	
+	if (ctxt->nameNr < depth) break;
+    }
 
     /*
      * Capture end position and add node
@@ -4107,10 +4261,305 @@
 	xmlFree(currentNode);
 }
 
+static void
+htmlParserFinishElementParsing(htmlParserCtxtPtr ctxt) {
+    /*
+     * Capture end position and add node
+     */
+    if ( ctxt->node != NULL && ctxt->record_info ) {
+       ctxt->nodeInfo->end_pos = ctxt->input->consumed +
+                                (CUR_PTR - ctxt->input->base);
+       ctxt->nodeInfo->end_line = ctxt->input->line;
+       ctxt->nodeInfo->node = ctxt->node;
+       xmlParserAddNodeInfo(ctxt, ctxt->nodeInfo);
+       htmlNodeInfoPop(ctxt);
+    }
+    if (!IS_CHAR_CH(CUR)) {
+       htmlAutoCloseOnEnd(ctxt);
+    }
+}
+
+/**
+ * htmlParseElementInternal:
+ * @ctxt:  an HTML parser context
+ *
+ * parse an HTML element, new version, non recursive
+ *
+ * [39] element ::= EmptyElemTag | STag content ETag
+ *
+ * [41] Attribute ::= Name Eq AttValue
+ */
+
+static void
+htmlParseElementInternal(htmlParserCtxtPtr ctxt) {
+    const xmlChar *name;
+    const htmlElemDesc * info;
+    htmlParserNodeInfo node_info;
+    int failed;
+
+    if ((ctxt == NULL) || (ctxt->input == NULL)) {
+	htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
+		     "htmlParseElementInternal: context error\n", NULL, NULL);
+	return;
+    }
+
+    if (ctxt->instate == XML_PARSER_EOF)
+        return;
+
+    /* Capture start position */
+    if (ctxt->record_info) {
+        node_info.begin_pos = ctxt->input->consumed +
+                          (CUR_PTR - ctxt->input->base);
+	node_info.begin_line = ctxt->input->line;
+    }
+
+    failed = htmlParseStartTag(ctxt);
+    name = ctxt->name;
+    if ((failed == -1) || (name == NULL)) {
+	if (CUR == '>')
+	    NEXT;
+        return;
+    }
+
+    /*
+     * Lookup the info for that element.
+     */
+    info = htmlTagLookup(name);
+    if (info == NULL) {
+	htmlParseErr(ctxt, XML_HTML_UNKNOWN_TAG,
+	             "Tag %s invalid\n", name, NULL);
+    }
+
+    /*
+     * Check for an Empty Element labeled the XML/SGML way
+     */
+    if ((CUR == '/') && (NXT(1) == '>')) {
+        SKIP(2);
+	if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
+	    ctxt->sax->endElement(ctxt->userData, name);
+	htmlnamePop(ctxt);
+	return;
+    }
+
+    if (CUR == '>') {
+        NEXT;
+    } else {
+	htmlParseErr(ctxt, XML_ERR_GT_REQUIRED,
+	             "Couldn't find end of Start Tag %s\n", name, NULL);
+
+	/*
+	 * end of parsing of this node.
+	 */
+	if (xmlStrEqual(name, ctxt->name)) {
+	    nodePop(ctxt);
+	    htmlnamePop(ctxt);
+	}
+
+        if (ctxt->record_info)
+            htmlNodeInfoPush(ctxt, &node_info);
+        htmlParserFinishElementParsing(ctxt);
+	return;
+    }
+
+    /*
+     * Check for an Empty Element from DTD definition
+     */
+    if ((info != NULL) && (info->empty)) {
+	if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
+	    ctxt->sax->endElement(ctxt->userData, name);
+	htmlnamePop(ctxt);
+	return;
+    }
+
+    if (ctxt->record_info)
+        htmlNodeInfoPush(ctxt, &node_info);
+}
+
+/**
+ * htmlParseContentInternal:
+ * @ctxt:  an HTML parser context
+ *
+ * Parse a content: comment, sub-element, reference or text.
+ * New version for non recursive htmlParseElementInternal
+ */
+
+static void
+htmlParseContentInternal(htmlParserCtxtPtr ctxt) {
+    xmlChar *currentNode;
+    int depth;
+    const xmlChar *name;
+
+    currentNode = xmlStrdup(ctxt->name);
+    depth = ctxt->nameNr;
+    while (1) {
+	long cons = ctxt->nbChars;
+
+        GROW;
+
+        if (ctxt->instate == XML_PARSER_EOF)
+            break;
+
+	/*
+	 * Our tag or one of it's parent or children is ending.
+	 */
+        if ((CUR == '<') && (NXT(1) == '/')) {
+	    if (htmlParseEndTag(ctxt) &&
+		((currentNode != NULL) || (ctxt->nameNr == 0))) {
+		if (currentNode != NULL)
+		    xmlFree(currentNode);
+
+	        currentNode = xmlStrdup(ctxt->name);
+	        depth = ctxt->nameNr;
+	    }
+	    continue; /* while */
+        }
+
+	else if ((CUR == '<') &&
+	         ((IS_ASCII_LETTER(NXT(1))) ||
+		  (NXT(1) == '_') || (NXT(1) == ':'))) {
+	    name = htmlParseHTMLName_nonInvasive(ctxt);
+	    if (name == NULL) {
+	        htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED,
+			 "htmlParseStartTag: invalid element name\n",
+			 NULL, NULL);
+	        /* Dump the bogus tag like browsers do */
+	        while ((IS_CHAR_CH(CUR)) && (CUR != '>'))
+	            NEXT;
+
+	        htmlParserFinishElementParsing(ctxt);
+	        if (currentNode != NULL)
+	            xmlFree(currentNode);
+
+	        currentNode = xmlStrdup(ctxt->name);
+	        depth = ctxt->nameNr;
+	        continue;
+	    }
+
+	    if (ctxt->name != NULL) {
+	        if (htmlCheckAutoClose(name, ctxt->name) == 1) {
+	            htmlAutoClose(ctxt, name);
+	            continue;
+	        }
+	    }
+	}
+
+	/*
+	 * Has this node been popped out during parsing of
+	 * the next element
+	 */
+        if ((ctxt->nameNr > 0) && (depth >= ctxt->nameNr) &&
+	    (!xmlStrEqual(currentNode, ctxt->name)))
+	     {
+	    htmlParserFinishElementParsing(ctxt);
+	    if (currentNode != NULL) xmlFree(currentNode);
+
+	    currentNode = xmlStrdup(ctxt->name);
+	    depth = ctxt->nameNr;
+	    continue;
+	}
+
+	if ((CUR != 0) && ((xmlStrEqual(currentNode, BAD_CAST"script")) ||
+	    (xmlStrEqual(currentNode, BAD_CAST"style")))) {
+	    /*
+	     * Handle SCRIPT/STYLE separately
+	     */
+	    htmlParseScript(ctxt);
+	} else {
+	    /*
+	     * Sometimes DOCTYPE arrives in the middle of the document
+	     */
+	    if ((CUR == '<') && (NXT(1) == '!') &&
+		(UPP(2) == 'D') && (UPP(3) == 'O') &&
+		(UPP(4) == 'C') && (UPP(5) == 'T') &&
+		(UPP(6) == 'Y') && (UPP(7) == 'P') &&
+		(UPP(8) == 'E')) {
+		htmlParseErr(ctxt, XML_HTML_STRUCURE_ERROR,
+		             "Misplaced DOCTYPE declaration\n",
+			     BAD_CAST "DOCTYPE" , NULL);
+		htmlParseDocTypeDecl(ctxt);
+	    }
+
+	    /*
+	     * First case :  a comment
+	     */
+	    if ((CUR == '<') && (NXT(1) == '!') &&
+		(NXT(2) == '-') && (NXT(3) == '-')) {
+		htmlParseComment(ctxt);
+	    }
+
+	    /*
+	     * Second case : a Processing Instruction.
+	     */
+	    else if ((CUR == '<') && (NXT(1) == '?')) {
+		htmlParsePI(ctxt);
+	    }
+
+	    /*
+	     * Third case :  a sub-element.
+	     */
+	    else if (CUR == '<') {
+		htmlParseElementInternal(ctxt);
+		if (currentNode != NULL) xmlFree(currentNode);
+
+		currentNode = xmlStrdup(ctxt->name);
+		depth = ctxt->nameNr;
+	    }
+
+	    /*
+	     * Fourth case : a reference. If if has not been resolved,
+	     *    parsing returns it's Name, create the node
+	     */
+	    else if (CUR == '&') {
+		htmlParseReference(ctxt);
+	    }
+
+	    /*
+	     * Fifth case : end of the resource
+	     */
+	    else if (CUR == 0) {
+		htmlAutoCloseOnEnd(ctxt);
+		break;
+	    }
+
+	    /*
+	     * Last case, text. Note that References are handled directly.
+	     */
+	    else {
+		htmlParseCharData(ctxt);
+	    }
+
+	    if (cons == ctxt->nbChars) {
+		if (ctxt->node != NULL) {
+		    htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
+		                 "detected an error in element content\n",
+				 NULL, NULL);
+		}
+		break;
+	    }
+	}
+        GROW;
+    }
+    if (currentNode != NULL) xmlFree(currentNode);
+}
+
+/**
+ * htmlParseContent:
+ * @ctxt:  an HTML parser context
+ *
+ * Parse a content: comment, sub-element, reference or text.
+ * This is the entry point when called from parser.c
+ */
+
+void
+__htmlParseContent(void *ctxt) {
+    if (ctxt != NULL)
+	htmlParseContentInternal((htmlParserCtxtPtr) ctxt);
+}
+
 /**
  * htmlParseDocument:
  * @ctxt:  an HTML parser context
- * 
+ *
  * parse an HTML document (and build a tree if using the standard SAX
  * interface).
  *
@@ -4134,6 +4583,7 @@
 	return(XML_ERR_INTERNAL_ERROR);
     }
     ctxt->html = 1;
+    ctxt->linenumbers = 1;
     GROW;
     /*
      * SAX: beginning of the document processing.
@@ -4163,7 +4613,7 @@
      */
     SKIP_BLANKS;
     if (CUR == 0) {
-	htmlParseErr(ctxt, XML_ERR_DOCUMENT_EMPTY, 
+	htmlParseErr(ctxt, XML_ERR_DOCUMENT_EMPTY,
 	             "Document is empty\n", NULL, NULL);
     }
 
@@ -4202,15 +4652,15 @@
     while (((CUR == '<') && (NXT(1) == '!') &&
             (NXT(2) == '-') && (NXT(3) == '-')) ||
 	   ((CUR == '<') && (NXT(1) == '?'))) {
-        htmlParseComment(ctxt);	   
-        htmlParsePI(ctxt);	   
+        htmlParseComment(ctxt);
+        htmlParsePI(ctxt);
 	SKIP_BLANKS;
-    }	   
+    }
 
     /*
      * Time to start parsing the tree itself
      */
-    htmlParseContent(ctxt);
+    htmlParseContentInternal(ctxt);
 
     /*
      * autoclose
@@ -4225,11 +4675,11 @@
     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
         ctxt->sax->endDocument(ctxt->userData);
 
-    if (ctxt->myDoc != NULL) {
+    if ((!(ctxt->options & HTML_PARSE_NODEFDTD)) && (ctxt->myDoc != NULL)) {
 	dtd = xmlGetIntSubset(ctxt->myDoc);
 	if (dtd == NULL)
-	    ctxt->myDoc->intSubset = 
-		xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "html", 
+	    ctxt->myDoc->intSubset =
+		xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "html",
 		    BAD_CAST "-//W3C//DTD HTML 4.0 Transitional//EN",
 		    BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd");
     }
@@ -4275,7 +4725,7 @@
         memset(sax, 0, sizeof(htmlSAXHandler));
 
     /* Allocate the Input stack */
-    ctxt->inputTab = (htmlParserInputPtr *) 
+    ctxt->inputTab = (htmlParserInputPtr *)
                       xmlMalloc(5 * sizeof(htmlParserInputPtr));
     if (ctxt->inputTab == NULL) {
         htmlErrMemory(NULL, "htmlInitParserCtxt: out of memory\n");
@@ -4313,7 +4763,7 @@
     if (ctxt->nameTab == NULL) {
         htmlErrMemory(NULL, "htmlInitParserCtxt: out of memory\n");
 	ctxt->nameNr = 0;
-	ctxt->nameMax = 10;
+	ctxt->nameMax = 0;
 	ctxt->name = NULL;
 	ctxt->nodeNr = 0;
 	ctxt->nodeMax = 0;
@@ -4327,6 +4777,10 @@
     ctxt->nameMax = 10;
     ctxt->name = NULL;
 
+    ctxt->nodeInfoTab = NULL;
+    ctxt->nodeInfoNr  = 0;
+    ctxt->nodeInfoMax = 0;
+
     if (sax == NULL) ctxt->sax = (xmlSAXHandlerPtr) &htmlDefaultSAXHandler;
     else {
         ctxt->sax = sax;
@@ -4473,7 +4927,7 @@
 	    xmlSwitchEncoding(ctxt, enc);
 	    if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
 		htmlParseErr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
-		             "Unsupported encoding %s\n", 
+		             "Unsupported encoding %s\n",
 			     (const xmlChar *) encoding, NULL);
 	    }
 	} else {
@@ -4496,7 +4950,7 @@
 #ifdef LIBXML_PUSH_ENABLED
 /************************************************************************
  *									*
- * 		Progressive parsing interfaces				*
+ *	Progressive parsing interfaces				*
  *									*
  ************************************************************************/
 
@@ -4520,85 +4974,190 @@
  */
 static int
 htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first,
-                        xmlChar next, xmlChar third, int iscomment) {
+                        xmlChar next, xmlChar third, int iscomment,
+                        int ignoreattrval)
+{
     int base, len;
     htmlParserInputPtr in;
     const xmlChar *buf;
     int incomment = 0;
+    int invalue = 0;
+    char valdellim = 0x0;
 
     in = ctxt->input;
-    if (in == NULL) return(-1);
+    if (in == NULL)
+        return (-1);
+
     base = in->cur - in->base;
-    if (base < 0) return(-1);
+    if (base < 0)
+        return (-1);
+
     if (ctxt->checkIndex > base)
         base = ctxt->checkIndex;
+
     if (in->buf == NULL) {
-	buf = in->base;
-	len = in->length;
+        buf = in->base;
+        len = in->length;
     } else {
-	buf = in->buf->buffer->content;
-	len = in->buf->buffer->use;
+        buf = in->buf->buffer->content;
+        len = in->buf->buffer->use;
     }
+
     /* take into account the sequence length */
-    if (third) len -= 2;
-    else if (next) len --;
-    for (;base < len;base++) {
-	if (!incomment && (base + 4 < len) && !iscomment) {
-	    if ((buf[base] == '<') && (buf[base + 1] == '!') &&
-		(buf[base + 2] == '-') && (buf[base + 3] == '-')) {
-		incomment = 1;
-		/* do not increment past <! - some people use <!--> */
-		base += 2;
-	    }
-	}
-	if (incomment) {
-	    if (base + 3 > len)
-		return(-1);
-	    if ((buf[base] == '-') && (buf[base + 1] == '-') &&
-		(buf[base + 2] == '>')) {
-		incomment = 0;
-		base += 2;
-	    }
-	    continue;
-	}
+    if (third)
+        len -= 2;
+    else if (next)
+        len--;
+    for (; base < len; base++) {
+        if ((!incomment) && (base + 4 < len) && (!iscomment)) {
+            if ((buf[base] == '<') && (buf[base + 1] == '!') &&
+                (buf[base + 2] == '-') && (buf[base + 3] == '-')) {
+                incomment = 1;
+                /* do not increment past <! - some people use <!--> */
+                base += 2;
+            }
+        }
+        if (ignoreattrval) {
+            if (buf[base] == '"' || buf[base] == '\'') {
+                if (invalue) {
+                    if (buf[base] == valdellim) {
+                        invalue = 0;
+                        continue;
+                    }
+                } else {
+                    valdellim = buf[base];
+                    invalue = 1;
+                    continue;
+                }
+            } else if (invalue) {
+                continue;
+            }
+        }
+        if (incomment) {
+            if (base + 3 > len)
+                return (-1);
+            if ((buf[base] == '-') && (buf[base + 1] == '-') &&
+                (buf[base + 2] == '>')) {
+                incomment = 0;
+                base += 2;
+            }
+            continue;
+        }
         if (buf[base] == first) {
-	    if (third != 0) {
-		if ((buf[base + 1] != next) ||
-		    (buf[base + 2] != third)) continue;
-	    } else if (next != 0) {
-		if (buf[base + 1] != next) continue;
-	    }
-	    ctxt->checkIndex = 0;
+            if (third != 0) {
+                if ((buf[base + 1] != next) || (buf[base + 2] != third))
+                    continue;
+            } else if (next != 0) {
+                if (buf[base + 1] != next)
+                    continue;
+            }
+            ctxt->checkIndex = 0;
 #ifdef DEBUG_PUSH
-	    if (next == 0)
-		xmlGenericError(xmlGenericErrorContext,
-			"HPP: lookup '%c' found at %d\n",
-			first, base);
-	    else if (third == 0)
-		xmlGenericError(xmlGenericErrorContext,
-			"HPP: lookup '%c%c' found at %d\n",
-			first, next, base);
-	    else 
-		xmlGenericError(xmlGenericErrorContext,
-			"HPP: lookup '%c%c%c' found at %d\n",
-			first, next, third, base);
+            if (next == 0)
+                xmlGenericError(xmlGenericErrorContext,
+                                "HPP: lookup '%c' found at %d\n",
+                                first, base);
+            else if (third == 0)
+                xmlGenericError(xmlGenericErrorContext,
+                                "HPP: lookup '%c%c' found at %d\n",
+                                first, next, base);
+            else
+                xmlGenericError(xmlGenericErrorContext,
+                                "HPP: lookup '%c%c%c' found at %d\n",
+                                first, next, third, base);
 #endif
-	    return(base - (in->cur - in->base));
-	}
+            return (base - (in->cur - in->base));
+        }
     }
-    ctxt->checkIndex = base;
+    if ((!incomment) && (!invalue))
+        ctxt->checkIndex = base;
 #ifdef DEBUG_PUSH
     if (next == 0)
-	xmlGenericError(xmlGenericErrorContext,
-		"HPP: lookup '%c' failed\n", first);
+        xmlGenericError(xmlGenericErrorContext,
+                        "HPP: lookup '%c' failed\n", first);
     else if (third == 0)
-	xmlGenericError(xmlGenericErrorContext,
-		"HPP: lookup '%c%c' failed\n", first, next);
-    else	
-	xmlGenericError(xmlGenericErrorContext,
-		"HPP: lookup '%c%c%c' failed\n", first, next, third);
+        xmlGenericError(xmlGenericErrorContext,
+                        "HPP: lookup '%c%c' failed\n", first, next);
+    else
+        xmlGenericError(xmlGenericErrorContext,
+                        "HPP: lookup '%c%c%c' failed\n", first, next,
+                        third);
 #endif
-    return(-1);
+    return (-1);
+}
+
+/**
+ * htmlParseLookupChars:
+ * @ctxt: an HTML parser context
+ * @stop: Array of chars, which stop the lookup.
+ * @stopLen: Length of stop-Array
+ *
+ * Try to find if any char of the stop-Array is available in the input 
+ * stream.
+ * This function has a side effect of (possibly) incrementing ctxt->checkIndex
+ * to avoid rescanning sequences of bytes, it DOES change the state of the
+ * parser, do not use liberally.
+ *
+ * Returns the index to the current parsing point if a stopChar 
+ *      is available, -1 otherwise.
+ */
+static int
+htmlParseLookupChars(htmlParserCtxtPtr ctxt, const xmlChar * stop,
+                     int stopLen)
+{
+    int base, len;
+    htmlParserInputPtr in;
+    const xmlChar *buf;
+    int incomment = 0;
+    int i;
+
+    in = ctxt->input;
+    if (in == NULL)
+        return (-1);
+
+    base = in->cur - in->base;
+    if (base < 0)
+        return (-1);
+
+    if (ctxt->checkIndex > base)
+        base = ctxt->checkIndex;
+
+    if (in->buf == NULL) {
+        buf = in->base;
+        len = in->length;
+    } else {
+        buf = in->buf->buffer->content;
+        len = in->buf->buffer->use;
+    }
+
+    for (; base < len; base++) {
+        if (!incomment && (base + 4 < len)) {
+            if ((buf[base] == '<') && (buf[base + 1] == '!') &&
+                (buf[base + 2] == '-') && (buf[base + 3] == '-')) {
+                incomment = 1;
+                /* do not increment past <! - some people use <!--> */
+                base += 2;
+            }
+        }
+        if (incomment) {
+            if (base + 3 > len)
+                return (-1);
+            if ((buf[base] == '-') && (buf[base + 1] == '-') &&
+                (buf[base + 2] == '>')) {
+                incomment = 0;
+                base += 2;
+            }
+            continue;
+        }
+        for (i = 0; i < stopLen; ++i) {
+            if (buf[base] == stop[i]) {
+                ctxt->checkIndex = 0;
+                return (base - (in->cur - in->base));
+            }
+        }
+    }
+    ctxt->checkIndex = base;
+    return (-1);
 }
 
 /**
@@ -4680,7 +5239,7 @@
 	    avail = in->buf->buffer->use - (in->cur - in->base);
 	if ((avail == 0) && (terminate)) {
 	    htmlAutoCloseOnEnd(ctxt);
-	    if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) { 
+	    if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) {
 		/*
 		 * SAX: end of the document processing.
 		 */
@@ -4730,7 +5289,7 @@
 		    (UPP(6) == 'Y') && (UPP(7) == 'P') &&
 		    (UPP(8) == 'E')) {
 		    if ((!terminate) &&
-		        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
+		        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
 			goto done;
 #ifdef DEBUG_PUSH
 		    xmlGenericError(xmlGenericErrorContext,
@@ -4763,7 +5322,7 @@
 	        if ((cur == '<') && (next == '!') &&
 		    (in->cur[2] == '-') && (in->cur[3] == '-')) {
 		    if ((!terminate) &&
-		        (htmlParseLookupSequence(ctxt, '-', '-', '>', 1) < 0))
+		        (htmlParseLookupSequence(ctxt, '-', '-', '>', 1, 1) < 0))
 			goto done;
 #ifdef DEBUG_PUSH
 		    xmlGenericError(xmlGenericErrorContext,
@@ -4773,7 +5332,7 @@
 		    ctxt->instate = XML_PARSER_MISC;
 	        } else if ((cur == '<') && (next == '?')) {
 		    if ((!terminate) &&
-		        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
+		        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
 			goto done;
 #ifdef DEBUG_PUSH
 		    xmlGenericError(xmlGenericErrorContext,
@@ -4787,7 +5346,7 @@
 		    (UPP(6) == 'Y') && (UPP(7) == 'P') &&
 		    (UPP(8) == 'E')) {
 		    if ((!terminate) &&
-		        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
+		        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
 			goto done;
 #ifdef DEBUG_PUSH
 		    xmlGenericError(xmlGenericErrorContext,
@@ -4816,14 +5375,14 @@
 		    avail = in->length - (in->cur - in->base);
 		else
 		    avail = in->buf->buffer->use - (in->cur - in->base);
-		if (avail < 2) 
+		if (avail < 2)
 		    goto done;
 		cur = in->cur[0];
 		next = in->cur[1];
 		if ((cur == '<') && (next == '!') &&
 		    (in->cur[2] == '-') && (in->cur[3] == '-')) {
 		    if ((!terminate) &&
-		        (htmlParseLookupSequence(ctxt, '-', '-', '>', 1) < 0))
+		        (htmlParseLookupSequence(ctxt, '-', '-', '>', 1, 1) < 0))
 			goto done;
 #ifdef DEBUG_PUSH
 		    xmlGenericError(xmlGenericErrorContext,
@@ -4833,7 +5392,7 @@
 		    ctxt->instate = XML_PARSER_PROLOG;
 	        } else if ((cur == '<') && (next == '?')) {
 		    if ((!terminate) &&
-		        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
+		        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
 			goto done;
 #ifdef DEBUG_PUSH
 		    xmlGenericError(xmlGenericErrorContext,
@@ -4870,7 +5429,7 @@
 	        if ((cur == '<') && (next == '!') &&
 		    (in->cur[2] == '-') && (in->cur[3] == '-')) {
 		    if ((!terminate) &&
-		        (htmlParseLookupSequence(ctxt, '-', '-', '>', 1) < 0))
+		        (htmlParseLookupSequence(ctxt, '-', '-', '>', 1, 1) < 0))
 			goto done;
 #ifdef DEBUG_PUSH
 		    xmlGenericError(xmlGenericErrorContext,
@@ -4880,7 +5439,7 @@
 		    ctxt->instate = XML_PARSER_EPILOG;
 	        } else if ((cur == '<') && (next == '?')) {
 		    if ((!terminate) &&
-		        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
+		        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
 			goto done;
 #ifdef DEBUG_PUSH
 		    xmlGenericError(xmlGenericErrorContext,
@@ -4930,7 +5489,7 @@
 		    break;
 		}
 		if ((!terminate) &&
-		    (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
+		    (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
 		    goto done;
 
 		failed = htmlParseStartTag(ctxt);
@@ -4977,10 +5536,10 @@
 		    /*
 		     * end of parsing of this node.
 		     */
-		    if (xmlStrEqual(name, ctxt->name)) { 
+		    if (xmlStrEqual(name, ctxt->name)) {
 			nodePop(ctxt);
 			htmlnamePop(ctxt);
-		    }    
+		    }
 
 		    ctxt->instate = XML_PARSER_CONTENT;
 #ifdef DEBUG_PUSH
@@ -5055,7 +5614,7 @@
 		        int idx;
 			xmlChar val;
 
-			idx = htmlParseLookupSequence(ctxt, '<', '/', 0, 0);
+			idx = htmlParseLookupSequence(ctxt, '<', '/', 0, 0, 0);
 			if (idx < 0)
 			    goto done;
 		        val = in->cur[idx + 2];
@@ -5082,7 +5641,7 @@
 			(UPP(6) == 'Y') && (UPP(7) == 'P') &&
 			(UPP(8) == 'E')) {
 			if ((!terminate) &&
-			    (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
+			    (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
 			    goto done;
 			htmlParseErr(ctxt, XML_HTML_STRUCURE_ERROR,
 			             "Misplaced DOCTYPE declaration\n",
@@ -5092,7 +5651,7 @@
 			(in->cur[2] == '-') && (in->cur[3] == '-')) {
 			if ((!terminate) &&
 			    (htmlParseLookupSequence(
-			    		ctxt, '-', '-', '>', 1) < 0))
+				ctxt, '-', '-', '>', 1, 1) < 0))
 			    goto done;
 #ifdef DEBUG_PUSH
 			xmlGenericError(xmlGenericErrorContext,
@@ -5102,7 +5661,7 @@
 			ctxt->instate = XML_PARSER_CONTENT;
 		    } else if ((cur == '<') && (next == '?')) {
 			if ((!terminate) &&
-			    (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
+			    (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
 			    goto done;
 #ifdef DEBUG_PUSH
 			xmlGenericError(xmlGenericErrorContext,
@@ -5130,7 +5689,8 @@
 			break;
 		    } else if (cur == '&') {
 			if ((!terminate) &&
-			    (htmlParseLookupSequence(ctxt, ';', 0, 0, 0) < 0))
+			    (htmlParseLookupChars(ctxt,
+                                                  BAD_CAST "; >/", 4) < 0))
 			    goto done;
 #ifdef DEBUG_PUSH
 			xmlGenericError(xmlGenericErrorContext,
@@ -5146,7 +5706,7 @@
 			 * data detection.
 			 */
 			if ((!terminate) &&
-			    (htmlParseLookupSequence(ctxt, '<', 0, 0, 0) < 0))
+                            (htmlParseLookupChars(ctxt, BAD_CAST "<&", 2) < 0))
 			    goto done;
 			ctxt->checkIndex = 0;
 #ifdef DEBUG_PUSH
@@ -5172,7 +5732,7 @@
 		if (avail < 2)
 		    goto done;
 		if ((!terminate) &&
-		    (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
+		    (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
 		    goto done;
 		htmlParseEndTag(ctxt);
 		if (ctxt->nameNr == 0) {
@@ -5299,10 +5859,10 @@
 
 	}
     }
-done:    
+done:
     if ((avail == 0) && (terminate)) {
 	htmlAutoCloseOnEnd(ctxt);
-	if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) { 
+	if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) {
 	    /*
 	     * SAX: end of the document processing.
 	     */
@@ -5317,8 +5877,8 @@
 	xmlDtdPtr dtd;
 	dtd = xmlGetIntSubset(ctxt->myDoc);
 	if (dtd == NULL)
-	    ctxt->myDoc->intSubset = 
-		xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "html", 
+	    ctxt->myDoc->intSubset =
+		xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "html",
 		    BAD_CAST "-//W3C//DTD HTML 4.0 Transitional//EN",
 		    BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd");
     }
@@ -5352,8 +5912,8 @@
 	int base = ctxt->input->base - ctxt->input->buf->buffer->content;
 	int cur = ctxt->input->cur - ctxt->input->base;
 	int res;
-	
-	res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);	      
+
+	res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
 	if (res < 0) {
 	    ctxt->errNo = XML_PARSER_EOF;
 	    ctxt->disableSAX = 1;
@@ -5377,7 +5937,7 @@
 	    if ((in->encoder != NULL) && (in->buffer != NULL) &&
 		    (in->raw != NULL)) {
 		int nbchars;
-		    
+
 		nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
 		if (nbchars < 0) {
 		    htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING,
@@ -5394,14 +5954,14 @@
 	    (ctxt->instate != XML_PARSER_MISC)) {
 	    ctxt->errNo = XML_ERR_DOCUMENT_END;
 	    ctxt->wellFormed = 0;
-	} 
+	}
 	if (ctxt->instate != XML_PARSER_EOF) {
 	    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
 		ctxt->sax->endDocument(ctxt->userData);
 	}
 	ctxt->instate = XML_PARSER_EOF;
     }
-    return((xmlParserErrors) ctxt->errNo);	      
+    return((xmlParserErrors) ctxt->errNo);
 }
 
 /************************************************************************
@@ -5426,7 +5986,7 @@
  * Returns the new parser context or NULL
  */
 htmlParserCtxtPtr
-htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax, void *user_data, 
+htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax, void *user_data,
                          const char *chunk, int size, const char *filename,
 			 xmlCharEncoding enc) {
     htmlParserCtxtPtr ctxt;
@@ -5457,7 +6017,7 @@
 	memcpy(ctxt->sax, sax, sizeof(htmlSAXHandler));
 	if (user_data != NULL)
 	    ctxt->userData = user_data;
-    }	
+    }
     if (filename == NULL) {
 	ctxt->directory = NULL;
     } else {
@@ -5479,17 +6039,17 @@
     inputStream->buf = buf;
     inputStream->base = inputStream->buf->buffer->content;
     inputStream->cur = inputStream->buf->buffer->content;
-    inputStream->end = 
+    inputStream->end =
 	&inputStream->buf->buffer->content[inputStream->buf->buffer->use];
 
     inputPush(ctxt, inputStream);
 
     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
-        (ctxt->input->buf != NULL))  {	      
+        (ctxt->input->buf != NULL))  {
 	int base = ctxt->input->base - ctxt->input->buf->buffer->content;
 	int cur = ctxt->input->cur - ctxt->input->base;
 
-	xmlParserInputBufferPush(ctxt->input->buf, size, chunk);	      
+	xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
 
 	ctxt->input->base = ctxt->input->buf->buffer->content + base;
 	ctxt->input->cur = ctxt->input->base + cur;
@@ -5510,12 +6070,12 @@
  * @cur:  a pointer to an array of xmlChar
  * @encoding:  a free form C string describing the HTML document encoding, or NULL
  * @sax:  the SAX handler block
- * @userData: if using SAX, this pointer will be provided on callbacks. 
+ * @userData: if using SAX, this pointer will be provided on callbacks.
  *
  * Parse an HTML in-memory document. If sax is not NULL, use the SAX callbacks
  * to handle parse events. If sax is NULL, fallback to the default DOM
  * behavior and return a tree.
- * 
+ *
  * Returns the resulting document tree unless SAX is NULL or the document is
  *     not well formed.
  */
@@ -5532,7 +6092,7 @@
 
     ctxt = htmlCreateDocParserCtxt(cur, encoding);
     if (ctxt == NULL) return(NULL);
-    if (sax != NULL) { 
+    if (sax != NULL) {
         if (ctxt->sax != NULL) xmlFree (ctxt->sax);
         ctxt->sax = sax;
         ctxt->userData = userData;
@@ -5545,7 +6105,7 @@
 	ctxt->userData = NULL;
     }
     htmlFreeParserCtxt(ctxt);
-    
+
     return(ret);
 }
 
@@ -5555,7 +6115,7 @@
  * @encoding:  a free form C string describing the HTML document encoding, or NULL
  *
  * parse an HTML in-memory document and build a tree.
- * 
+ *
  * Returns the resulting document tree
  */
 
@@ -5570,7 +6130,7 @@
  * @filename:  the filename
  * @encoding:  a free form C string describing the HTML document encoding, or NULL
  *
- * Create a parser context for a file content. 
+ * Create a parser context for a file content.
  * Automatic support for ZLIB/Compress compressed document is provided
  * by default if found at compile-time.
  *
@@ -5602,7 +6162,7 @@
 	xmlFreeParserCtxt(ctxt);
 	return(NULL);
     }
-    
+
     inputStream = xmlLoadExternalEntity(canonicFilename, NULL, ctxt);
     xmlFree(canonicFilename);
     if (inputStream == NULL) {
@@ -5615,14 +6175,14 @@
     /* set encoding */
     if (encoding) {
         content = xmlMallocAtomic (xmlStrlen(content_line) + strlen(encoding) + 1);
-	if (content) {  
+	if (content) {
 	    strcpy ((char *)content, (char *)content_line);
             strcat ((char *)content, (char *)encoding);
             htmlCheckEncoding (ctxt, content);
 	    xmlFree (content);
 	}
     }
-    
+
     return(ctxt);
 }
 
@@ -5631,7 +6191,7 @@
  * @filename:  the filename
  * @encoding:  a free form C string describing the HTML document encoding, or NULL
  * @sax:  the SAX handler block
- * @userData: if using SAX, this pointer will be provided on callbacks. 
+ * @userData: if using SAX, this pointer will be provided on callbacks.
  *
  * parse an HTML file and build a tree. Automatic support for ZLIB/Compress
  * compressed document is provided by default if found at compile-time.
@@ -5643,7 +6203,7 @@
  */
 
 htmlDocPtr
-htmlSAXParseFile(const char *filename, const char *encoding, htmlSAXHandlerPtr sax, 
+htmlSAXParseFile(const char *filename, const char *encoding, htmlSAXHandlerPtr sax,
                  void *userData) {
     htmlDocPtr ret;
     htmlParserCtxtPtr ctxt;
@@ -5667,7 +6227,7 @@
         ctxt->userData = NULL;
     }
     htmlFreeParserCtxt(ctxt);
-    
+
     return(ret);
 }
 
@@ -5689,7 +6249,7 @@
 
 /**
  * htmlHandleOmittedElem:
- * @val:  int 0 or 1 
+ * @val:  int 0 or 1
  *
  * Set and return the previous value for handling HTML omitted tags.
  *
@@ -5829,7 +6389,7 @@
  * current scope
  */
 #define DICT_FREE(str)						\
-	if ((str) && ((!dict) || 				\
+	if ((str) && ((!dict) ||				\
 	    (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))	\
 	    xmlFree((char *)(str));
 
@@ -5844,7 +6404,7 @@
 {
     xmlParserInputPtr input;
     xmlDictPtr dict;
-    
+
     if (ctxt == NULL)
         return;
 
@@ -5896,6 +6456,7 @@
 
     ctxt->wellFormed = 1;
     ctxt->nsWellFormed = 1;
+    ctxt->disableSAX = 0;
     ctxt->valid = 1;
     ctxt->vctxt.userData = ctxt;
     ctxt->vctxt.error = xmlParserValidityError;
@@ -5971,6 +6532,18 @@
 	ctxt->options |= HTML_PARSE_COMPACT;
         options -= HTML_PARSE_COMPACT;
     }
+    if (options & XML_PARSE_HUGE) {
+	ctxt->options |= XML_PARSE_HUGE;
+        options -= XML_PARSE_HUGE;
+    }
+    if (options & HTML_PARSE_NODEFDTD) {
+	ctxt->options |= HTML_PARSE_NODEFDTD;
+        options -= HTML_PARSE_NODEFDTD;
+    }
+    if (options & HTML_PARSE_IGNORE_ENC) {
+	ctxt->options |= HTML_PARSE_IGNORE_ENC;
+        options -= HTML_PARSE_IGNORE_ENC;
+    }
     ctxt->dictNames = 0;
     return (options);
 }
@@ -5984,7 +6557,7 @@
  * @reuse:  keep the context for reuse
  *
  * Common front-end for the htmlRead functions
- * 
+ *
  * Returns the resulting document tree or NULL
  */
 static htmlDocPtr
@@ -5992,7 +6565,7 @@
           int options, int reuse)
 {
     htmlDocPtr ret;
-    
+
     htmlCtxtUseOptions(ctxt, options);
     ctxt->html = 1;
     if (encoding != NULL) {
@@ -6030,7 +6603,7 @@
  * @options:  a combination of htmlParserOption(s)
  *
  * parse an XML in-memory document and build a tree.
- * 
+ *
  * Returns the resulting document tree
  */
 htmlDocPtr
@@ -6055,7 +6628,7 @@
  * @options:  a combination of htmlParserOption(s)
  *
  * parse an XML file from the filesystem or the network.
- * 
+ *
  * Returns the resulting document tree
  */
 htmlDocPtr
@@ -6079,7 +6652,7 @@
  * @options:  a combination of htmlParserOption(s)
  *
  * parse an XML in-memory document and build a tree.
- * 
+ *
  * Returns the resulting document tree
  */
 htmlDocPtr
@@ -6105,7 +6678,7 @@
  * @options:  a combination of htmlParserOption(s)
  *
  * parse an XML from a file descriptor and build a tree.
- * 
+ *
  * Returns the resulting document tree
  */
 htmlDocPtr
@@ -6147,7 +6720,7 @@
  * @options:  a combination of htmlParserOption(s)
  *
  * parse an HTML document from I/O functions and source and build a tree.
- * 
+ *
  * Returns the resulting document tree
  */
 htmlDocPtr
@@ -6191,7 +6764,7 @@
  *
  * parse an XML in-memory document and build a tree.
  * This reuses the existing @ctxt parser context
- * 
+ *
  * Returns the resulting document tree
  */
 htmlDocPtr
@@ -6224,7 +6797,7 @@
  *
  * parse an XML file from the filesystem or the network.
  * This reuses the existing @ctxt parser context
- * 
+ *
  * Returns the resulting document tree
  */
 htmlDocPtr
@@ -6259,7 +6832,7 @@
  *
  * parse an XML in-memory document and build a tree.
  * This reuses the existing @ctxt parser context
- * 
+ *
  * Returns the resulting document tree
  */
 htmlDocPtr
@@ -6301,7 +6874,7 @@
  *
  * parse an XML from a file descriptor and build a tree.
  * This reuses the existing @ctxt parser context
- * 
+ *
  * Returns the resulting document tree
  */
 htmlDocPtr
@@ -6343,7 +6916,7 @@
  *
  * parse an HTML document from I/O functions and source and build a tree.
  * This reuses the existing @ctxt parser context
- * 
+ *
  * Returns the resulting document tree
  */
 htmlDocPtr
diff --git a/HTMLtree.c b/HTMLtree.c
index 37999f7..f23ae02 100644
--- a/HTMLtree.c
+++ b/HTMLtree.c
@@ -160,14 +160,18 @@
  */
 int
 htmlSetMetaEncoding(htmlDocPtr doc, const xmlChar *encoding) {
-    htmlNodePtr cur, meta;
-    const xmlChar *content;
+    htmlNodePtr cur, meta = NULL, head = NULL;
+    const xmlChar *content = NULL;
     char newcontent[100];
 
 
     if (doc == NULL)
 	return(-1);
 
+    /* html isn't a real encoding it's just libxml2 way to get entities */
+    if (!xmlStrcasecmp(encoding, BAD_CAST "html"))
+        return(-1);
+
     if (encoding != NULL) {
 	snprintf(newcontent, sizeof(newcontent), "text/html; charset=%s",
                 (char *)encoding);
@@ -201,39 +205,24 @@
 	if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
 	    if (xmlStrcasecmp(cur->name, BAD_CAST"head") == 0)
 		break;
-	    if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0)
+	    if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0) {
+                head = cur->parent;
 		goto found_meta;
+            }
 	}
 	cur = cur->next;
     }
     if (cur == NULL)
 	return(-1);
 found_head:
-    if (cur->children == NULL) {
-	if (encoding == NULL)
-	    return(0);
-	meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
-	xmlAddChild(cur, meta);
-	xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
-	xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
-	return(0);
-    }
+    head = cur;
+    if (cur->children == NULL)
+        goto create;
     cur = cur->children;
 
 found_meta:
-    if (encoding != NULL) {
-	/*
-	 * Create a new Meta element with the right attributes
-	 */
-
-	meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
-	xmlAddPrevSibling(cur, meta);
-	xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
-	xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
-    }
-
     /*
-     * Search and destroy all the remaining the meta elements carrying
+     * Search and update all the remaining the meta elements carrying
      * encoding informations
      */
     while (cur != NULL) {
@@ -253,11 +242,11 @@
 			if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv"))
 			 && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
 			    http = 1;
-			else 
+			else
                         {
                            if ((value != NULL) && 
-				(!xmlStrcasecmp(attr->name, BAD_CAST"content")))
-			      content = value;
+                               (!xmlStrcasecmp(attr->name, BAD_CAST"content")))
+			       content = value;
                         }
 		        if ((http != 0) && (content != NULL))
 			    break;
@@ -266,16 +255,36 @@
 		}
 		if ((http != 0) && (content != NULL)) {
 		    meta = cur;
-		    cur = cur->next;
-		    xmlUnlinkNode(meta);
-                    xmlFreeNode(meta);
-		    continue;
+		    break;
 		}
 
 	    }
 	}
 	cur = cur->next;
     }
+create:
+    if (meta == NULL) {
+        if ((encoding != NULL) && (head != NULL)) {
+            /*
+             * Create a new Meta element with the right attributes
+             */
+
+            meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
+            if (head->children == NULL)
+                xmlAddChild(head, meta);
+            else
+                xmlAddPrevSibling(head->children, meta);
+            xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
+            xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
+        }
+    } else {
+        /* change the document only if there is a real encoding change */
+        if (xmlStrcasestr(content, encoding) == NULL) {
+            xmlSetProp(meta, BAD_CAST"content", BAD_CAST newcontent);
+        }
+    }
+
+
     return(0);
 }
 
@@ -472,7 +481,7 @@
 	if (enc != XML_CHAR_ENCODING_UTF8) {
 	    handler = xmlFindCharEncodingHandler(encoding);
 	    if (handler == NULL)
-		return(-1);
+		htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
 	}
     }
 
@@ -553,11 +562,9 @@
 	    }
 
 	    handler = xmlFindCharEncodingHandler(encoding);
-	    if (handler == NULL) {
-		*mem = NULL;
-		*size = 0;
-		return;
-	    }
+	    if (handler == NULL)
+                htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
+
 	} else {
 	    handler = xmlFindCharEncodingHandler(encoding);
 	}
@@ -578,7 +585,7 @@
 	return;
     }
 
-	htmlDocContentDumpFormatOutput(buf, cur, NULL, format);
+    htmlDocContentDumpFormatOutput(buf, cur, NULL, format);
 
     xmlOutputBufferFlush(buf);
     if (buf->conv != NULL) {
@@ -1052,7 +1059,7 @@
 
 	    handler = xmlFindCharEncodingHandler(encoding);
 	    if (handler == NULL)
-		return(-1);
+		htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
 	} else {
 	    handler = xmlFindCharEncodingHandler(encoding);
 	}
@@ -1111,7 +1118,7 @@
 
 	    handler = xmlFindCharEncodingHandler(encoding);
 	    if (handler == NULL)
-		return(-1);
+		htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
 	}
     }
 
@@ -1155,7 +1162,7 @@
 
     if ((cur == NULL) || (filename == NULL))
         return(-1);
-       
+
     xmlInitParser();
 
     if (encoding != NULL) {
@@ -1172,9 +1179,9 @@
 
 	    handler = xmlFindCharEncodingHandler(encoding);
 	    if (handler == NULL)
-		return(-1);
-            htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
+		htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
 	}
+        htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
     } else {
 	htmlSetMetaEncoding(cur, (const xmlChar *) "UTF-8");
     }
diff --git a/SAX2.c b/SAX2.c
index 164409c..e230cea 100644
--- a/SAX2.c
+++ b/SAX2.c
@@ -1105,24 +1105,33 @@
 	return;
     }
 
+#ifdef LIBXML_HTML_ENABLED
+    if ((ctxt->html) &&
+        (value == NULL) && (htmlIsBooleanAttr(fullname))) {
+            nval = xmlStrdup(fullname);
+            value = (const xmlChar *) nval;
+    } else
+#endif
+    {
 #ifdef LIBXML_VALID_ENABLED
-    /*
-     * Do the last stage of the attribute normalization
-     * Needed for HTML too:
-     *   http://www.w3.org/TR/html4/types.html#h-6.2
-     */
-    ctxt->vctxt.valid = 1;
-    nval = xmlValidCtxtNormalizeAttributeValue(&ctxt->vctxt,
-	                                   ctxt->myDoc, ctxt->node,
-					   fullname, value);
-    if (ctxt->vctxt.valid != 1) {
-	ctxt->valid = 0;
-    }
-    if (nval != NULL)
-	value = nval;
+        /*
+         * Do the last stage of the attribute normalization
+         * Needed for HTML too:
+         *   http://www.w3.org/TR/html4/types.html#h-6.2
+         */
+        ctxt->vctxt.valid = 1;
+        nval = xmlValidCtxtNormalizeAttributeValue(&ctxt->vctxt,
+                                               ctxt->myDoc, ctxt->node,
+                                               fullname, value);
+        if (ctxt->vctxt.valid != 1) {
+            ctxt->valid = 0;
+        }
+        if (nval != NULL)
+            value = nval;
 #else
-    nval = NULL;
+        nval = NULL;
 #endif /* LIBXML_VALID_ENABLED */
+    }
 
     /*
      * Check whether it's a namespace definition
@@ -1246,30 +1255,32 @@
     }
 
     if (ns != NULL) {
-	xmlAttrPtr prop;
 	namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
+
 	if (namespace == NULL) {
 	    xmlNsErrMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
 		    "Namespace prefix %s of attribute %s is not defined\n",
 		             ns, name);
-	}
+	} else {
+            xmlAttrPtr prop;
 
-	prop = ctxt->node->properties;
-	while (prop != NULL) {
-	    if (prop->ns != NULL) {
-		if ((xmlStrEqual(name, prop->name)) &&
-		    ((namespace == prop->ns) ||
-		     (xmlStrEqual(namespace->href, prop->ns->href)))) {
-			xmlNsErrMsg(ctxt, XML_ERR_ATTRIBUTE_REDEFINED,
-			        "Attribute %s in %s redefined\n",
-			                 name, namespace->href);
-		    ctxt->wellFormed = 0;
-		    if (ctxt->recovery == 0) ctxt->disableSAX = 1;
-		    goto error;
-		}
-	    }
-	    prop = prop->next;
-	}
+            prop = ctxt->node->properties;
+            while (prop != NULL) {
+                if (prop->ns != NULL) {
+                    if ((xmlStrEqual(name, prop->name)) &&
+                        ((namespace == prop->ns) ||
+                         (xmlStrEqual(namespace->href, prop->ns->href)))) {
+                            xmlNsErrMsg(ctxt, XML_ERR_ATTRIBUTE_REDEFINED,
+                                    "Attribute %s in %s redefined\n",
+                                             name, namespace->href);
+                        ctxt->wellFormed = 0;
+                        if (ctxt->recovery == 0) ctxt->disableSAX = 1;
+                        goto error;
+                    }
+                }
+                prop = prop->next;
+            }
+        }
     } else {
 	namespace = NULL;
     }
@@ -1420,6 +1431,10 @@
 		    } else {
 			fulln = xmlStrdup(attr->name);
 		    }
+                    if (fulln == NULL) {
+                        xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
+                        break;
+                    }
 
 		    /*
 		     * Check that the attribute is not declared in the
@@ -1442,6 +1457,7 @@
 				    (const char *)fulln,
 				    (const char *)attr->elem);
 		    }
+                    xmlFree(fulln);
 		}
 		attr = attr->nexth;
 	    }
@@ -2147,6 +2163,7 @@
     xmlNodePtr parent;
     xmlNsPtr last = NULL, ns;
     const xmlChar *uri, *pref;
+    xmlChar *lname = NULL;
     int i, j;
 
     if (ctx == NULL) return;
@@ -2166,6 +2183,20 @@
     }
 
     /*
+     * Take care of the rare case of an undefined namespace prefix
+     */
+    if ((prefix != NULL) && (URI == NULL)) {
+        if (ctxt->dictNames) {
+	    const xmlChar *fullname;
+
+	    fullname = xmlDictQLookup(ctxt->dict, prefix, localname);
+	    if (fullname != NULL)
+	        localname = fullname;
+	} else {
+	    lname = xmlBuildQName(localname, prefix, NULL, 0);
+	}
+    }
+    /*
      * allocate the node
      */
     if (ctxt->freeElems != NULL) {
@@ -2178,7 +2209,10 @@
 	if (ctxt->dictNames)
 	    ret->name = localname;
 	else {
-	    ret->name = xmlStrdup(localname);
+	    if (lname == NULL)
+		ret->name = xmlStrdup(localname);
+	    else
+	        ret->name = lname;
 	    if (ret->name == NULL) {
 	        xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
 		return;
@@ -2190,8 +2224,11 @@
 	if (ctxt->dictNames)
 	    ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, 
 	                               (xmlChar *) localname, NULL);
-	else
+	else if (lname == NULL)
 	    ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL);
+	else
+	    ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, 
+	                               (xmlChar *) lname, NULL);
 	if (ret == NULL) {
 	    xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
 	    return;
@@ -2226,8 +2263,12 @@
 	    if ((URI != NULL) && (prefix == pref))
 		ret->ns = ns;
 	} else {
-	    xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
-	    return;
+            /*
+             * any out of memory error would already have been raised
+             * but we can't be garanteed it's the actual error due to the
+             * API, best is to skip in this case
+             */
+	    continue;
 	}
 #ifdef LIBXML_VALID_ENABLED
 	if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
@@ -2278,9 +2319,14 @@
 	        xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
 		return;
 	    }
-	    xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
-			"Namespace prefix %s was not found\n",
-			prefix, NULL);
+            if (prefix != NULL)
+                xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
+                             "Namespace prefix %s was not found\n",
+                             prefix, NULL);
+            else
+                xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
+                             "Namespace default prefix was not found\n",
+                             NULL, NULL);
 	}
     }
 
@@ -2289,8 +2335,33 @@
      */
     if (nb_attributes > 0) {
         for (j = 0,i = 0;i < nb_attributes;i++,j+=5) {
+	    /*
+	     * Handle the rare case of an undefined atribute prefix
+	     */
+	    if ((attributes[j+1] != NULL) && (attributes[j+2] == NULL)) {
+		if (ctxt->dictNames) {
+		    const xmlChar *fullname;
+
+		    fullname = xmlDictQLookup(ctxt->dict, attributes[j+1],
+		                              attributes[j]);
+		    if (fullname != NULL) {
+			xmlSAX2AttributeNs(ctxt, fullname, NULL,
+			                   attributes[j+3], attributes[j+4]);
+		        continue;
+		    }
+		} else {
+		    lname = xmlBuildQName(attributes[j], attributes[j+1],
+		                          NULL, 0);
+		    if (lname != NULL) {
+			xmlSAX2AttributeNs(ctxt, lname, NULL,
+			                   attributes[j+3], attributes[j+4]);
+			xmlFree(lname);
+		        continue;
+		    }
+		}
+	    }
 	    xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],
-	                       attributes[j+3], attributes[j+4]);
+			       attributes[j+3], attributes[j+4]);
 	}
     }
 
@@ -2554,7 +2625,6 @@
 
     ret = xmlNewDocPI(ctxt->myDoc, target, data);
     if (ret == NULL) return;
-    parent = ctxt->node;
 
     if (ctxt->linenumbers) {
 	if (ctxt->input != NULL) {
diff --git a/ThirdPartyProject.prop b/ThirdPartyProject.prop
index 9ddc179..4467c98 100644
--- a/ThirdPartyProject.prop
+++ b/ThirdPartyProject.prop
@@ -1,7 +1,7 @@
 # Copyright 2010 Google Inc. All Rights Reserved.
 #Fri Jul 16 10:03:09 PDT 2010
-currentVersion=2.7.6
-version=2.7.3
+currentVersion=2.7.8
+version=2.7.8
 isNative=true
 name=libxml2
 keywords=libxml2
diff --git a/c14n.c b/c14n.c
index f333297..9c3cad2 100644
--- a/c14n.c
+++ b/c14n.c
@@ -60,9 +60,11 @@
     xmlC14NPosition pos;
     int parent_is_doc;
     xmlC14NVisibleNsStackPtr ns_rendered;
+    
+    /* C14N mode */
+    xmlC14NMode mode;
 
     /* exclusive canonicalization */
-    int exclusive;
     xmlChar **inclusive_ns_prefixes;
 
     /* error number */
@@ -117,6 +119,9 @@
 	(ctx)->is_visible_callback((ctx)->user_data, \
 		(xmlNodePtr)(node), (xmlNodePtr)(parent)) : 1)
 
+#define 	xmlC14NIsExclusive( ctx ) \
+    ( (ctx)->mode == XML_C14N_EXCLUSIVE_1_0 )
+
 /************************************************************************
  *									*
  * 		Some factorized error routines				*
@@ -492,9 +497,7 @@
 {
     return ((ns != NULL) &&
             (xmlStrEqual(ns->prefix, BAD_CAST "xml")) &&
-            (xmlStrEqual(ns->href,
-                         BAD_CAST
-                         "http://www.w3.org/XML/1998/namespace")));
+            (xmlStrEqual(ns->href, XML_XML_NAMESPACE)));
 }
 
 
@@ -713,7 +716,7 @@
         return (-1);
     }
 
-    if(!ctx->exclusive) {
+    if(!xmlC14NIsExclusive(ctx)) {
         xmlC14NErrParam("processing namespaces axis (exc c14n)");
         return (-1);
 
@@ -845,6 +848,25 @@
 
 
 /**
+ * xmlC14NIsXmlAttr:
+ * @attr: 		the attr to check
+ *  		
+ * Checks whether the given attribute is a default "xml:" namespace
+ * with href="http://www.w3.org/XML/1998/namespace"
+ *
+ * Returns 1 if the node is default or 0 otherwise
+ */
+
+/* todo: make it a define? */
+static int
+xmlC14NIsXmlAttr(xmlAttrPtr attr)
+{
+    return ((attr->ns != NULL) && 
+           (xmlC14NIsXmlNs(attr->ns) != 0));
+}
+
+
+/**
  * xmlC14NAttrsCompare:
  * @attr1:		the pointer tls o first attr
  * @attr2: 		the pointer to second attr
@@ -925,7 +947,7 @@
     xmlOutputBufferWriteString(ctx->buf, (const char *) attr->name);
     xmlOutputBufferWriteString(ctx->buf, "=\"");
 
-    value = xmlNodeListGetString(attr->doc, attr->children, 1);
+    value = xmlNodeListGetString(ctx->doc, attr->children, 1);
     /* todo: should we log an error if value==NULL ? */
     if (value != NULL) {
         buffer = xmlC11NNormalizeAttr(value);
@@ -943,10 +965,133 @@
 }
 
 /**
+ * xmlC14NFindHiddenParentAttr:
+ *
+ * Finds an attribute in a hidden parent node.
+ * 
+ * Returns a pointer to the attribute node (if found) or NULL otherwise.
+ */
+static xmlAttrPtr
+xmlC14NFindHiddenParentAttr(xmlC14NCtxPtr ctx, xmlNodePtr cur, const xmlChar * name, const xmlChar * ns)
+{
+    xmlAttrPtr res;
+    while((cur != NULL) && (!xmlC14NIsVisible(ctx, cur, cur->parent))) {
+        res = xmlHasNsProp(cur, name, ns);
+        if(res != NULL) {
+            return res;
+        }
+
+        cur = cur->parent;
+    }
+
+    return NULL;
+}
+
+/**
+ * xmlC14NFixupBaseAttr:
+ *
+ * Fixes up the xml:base attribute
+ *
+ * Returns the newly created attribute or NULL
+ */
+static xmlAttrPtr
+xmlC14NFixupBaseAttr(xmlC14NCtxPtr ctx, xmlAttrPtr xml_base_attr)
+{    
+    xmlChar * res = NULL;
+    xmlNodePtr cur;
+    xmlAttrPtr attr;
+    xmlChar * tmp_str;
+    xmlChar * tmp_str2;
+    int tmp_str_len;
+
+    if ((ctx == NULL) || (xml_base_attr == NULL) || (xml_base_attr->parent == NULL)) {
+        xmlC14NErrParam("processing xml:base attribute");
+        return (NULL);
+    }
+
+    /* start from current value */
+    res = xmlNodeListGetString(ctx->doc, xml_base_attr->children, 1);
+    if(res == NULL) {
+        xmlC14NErrInternal("processing xml:base attribute - can't get attr value");
+        return (NULL);
+    }
+
+    /* go up the stack until we find a node that we rendered already */
+    cur = xml_base_attr->parent->parent;
+    while((cur != NULL) && (!xmlC14NIsVisible(ctx, cur, cur->parent))) {
+        attr = xmlHasNsProp(cur, BAD_CAST "base", XML_XML_NAMESPACE);
+        if(attr != NULL) {
+            /* get attr value */
+            tmp_str = xmlNodeListGetString(ctx->doc, attr->children, 1);
+            if(tmp_str == NULL) {
+                xmlFree(res);
+
+                xmlC14NErrInternal("processing xml:base attribute - can't get attr value");
+                return (NULL);
+            } 
+
+            /* we need to add '/' if our current base uri ends with '..' or '.' 
+            to ensure that we are forced to go "up" all the time */
+            tmp_str_len = xmlStrlen(tmp_str);
+            if(tmp_str_len > 1 && tmp_str[tmp_str_len - 2] == '.') {
+                tmp_str2 = xmlStrcat(tmp_str, BAD_CAST "/");
+                if(tmp_str2 == NULL) {
+                    xmlFree(tmp_str);
+                    xmlFree(res);
+
+                    xmlC14NErrInternal("processing xml:base attribute - can't modify uri");
+                    return (NULL);
+                }
+
+                tmp_str = tmp_str2;
+            }
+
+            /* build uri */
+            tmp_str2 = xmlBuildURI(res, tmp_str); 
+            if(tmp_str2 == NULL) {
+                xmlFree(tmp_str);
+                xmlFree(res);
+
+                xmlC14NErrInternal("processing xml:base attribute - can't construct uri");
+                return (NULL);
+            }
+
+            /* cleanup and set the new res */
+            xmlFree(tmp_str);
+            xmlFree(res);
+            res = tmp_str2;
+        }
+
+        /* next */
+        cur = cur->parent;
+    }
+
+    /* check if result uri is empty or not */
+    if((res == NULL) || xmlStrEqual(res, BAD_CAST "")) {
+        xmlFree(res);
+        return (NULL);
+    }
+
+    /* create and return the new attribute node */
+    attr = xmlNewNsProp(NULL, xml_base_attr->ns, BAD_CAST "base", res);
+    if(attr == NULL) {
+        xmlFree(res);
+
+        xmlC14NErrInternal("processing xml:base attribute - can't construct attribute");
+        return (NULL);
+    }
+ 
+    /* done */
+    xmlFree(res);
+    return (attr);
+}
+
+/**
  * xmlC14NProcessAttrsAxis:
  * @ctx: 		the C14N context
  * @cur:		the current node
  * @parent_visible:	the visibility of parent node
+ * @all_parents_visible: the visibility of all parent nodes
  *
  * Prints out canonical attribute axis of the current node to the
  * buffer from C14N context as follows 
@@ -978,7 +1123,13 @@
 xmlC14NProcessAttrsAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int parent_visible)
 {
     xmlAttrPtr attr;
-    xmlListPtr list;
+    xmlListPtr list;    
+    xmlAttrPtr attrs_to_delete = NULL;
+    
+    /* special processing for 1.1 spec */
+    xmlAttrPtr xml_base_attr = NULL;
+    xmlAttrPtr xml_lang_attr = NULL;
+    xmlAttrPtr xml_space_attr = NULL;
 
     if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
         xmlC14NErrParam("processing attributes axis");
@@ -994,42 +1145,184 @@
         return (-1);
     }
 
-    /* 
-     * Add all visible attributes from current node. 
-     */
-    attr = cur->properties;
-    while (attr != NULL) {
-        /* check that attribute is visible */
-        if (xmlC14NIsVisible(ctx, attr, cur)) {
-            xmlListInsert(list, attr);
-        }
-        attr = attr->next;
-    }
-
-    /* 
-     * include attributes in "xml" namespace defined in ancestors
-     * (only for non-exclusive XML Canonicalization)
-     */
-    if (parent_visible && (!ctx->exclusive) && (cur->parent != NULL)
-        && (!xmlC14NIsVisible(ctx, cur->parent, cur->parent->parent))) {
-        /*
-         * If XPath node-set is not specified then the parent is always 
-         * visible!
+    switch(ctx->mode) {
+    case XML_C14N_1_0:
+        /* The processing of an element node E MUST be modified slightly when an XPath node-set is 
+         * given as input and the element's parent is omitted from the node-set. The method for processing 
+         * the attribute axis of an element E in the node-set is enhanced. All element nodes along E's 
+         * ancestor axis are examined for nearest occurrences of attributes in the xml namespace, such 
+         * as xml:lang and xml:space (whether or not they are in the node-set). From this list of attributes, 
+         * remove any that are in E's attribute axis (whether or not they are in the node-set). Then, 
+         * lexicographically merge this attribute list with the nodes of E's attribute axis that are in 
+         * the node-set. The result of visiting the attribute axis is computed by processing the attribute 
+         * nodes in this merged attribute list. 
          */
-        cur = cur->parent;
-        while (cur != NULL) {
-            attr = cur->properties;
-            while (attr != NULL) {
-                if ((attr->ns != NULL)
-                    && (xmlStrEqual(attr->ns->prefix, BAD_CAST "xml"))) {
-                    if (xmlListSearch(list, attr) == NULL) {
-                        xmlListInsert(list, attr);
-                    }
-                }
-                attr = attr->next;
+    
+        /* 
+         * Add all visible attributes from current node. 
+         */
+        attr = cur->properties;
+        while (attr != NULL) {
+            /* check that attribute is visible */
+            if (xmlC14NIsVisible(ctx, attr, cur)) {
+                xmlListInsert(list, attr);
             }
-            cur = cur->parent;
+            attr = attr->next;
         }
+
+        /* 
+         * Handle xml attributes
+         */
+        if (parent_visible && (cur->parent != NULL) && 
+            (!xmlC14NIsVisible(ctx, cur->parent, cur->parent->parent))) 
+        {
+            xmlNodePtr tmp;
+
+            /*
+             * If XPath node-set is not specified then the parent is always 
+             * visible!
+             */
+            tmp = cur->parent;
+            while (tmp != NULL) {
+                attr = tmp->properties;
+                while (attr != NULL) {
+                    if (xmlC14NIsXmlAttr(attr) != 0) {
+                        if (xmlListSearch(list, attr) == NULL) {
+                            xmlListInsert(list, attr);
+                        }
+                    }
+                    attr = attr->next;
+                }
+                tmp = tmp->parent;
+            }
+        }
+
+        /* done */
+        break;
+    case XML_C14N_EXCLUSIVE_1_0:
+        /* attributes in the XML namespace, such as xml:lang and xml:space 
+         * are not imported into orphan nodes of the document subset 
+         */
+
+        /* 
+         * Add all visible attributes from current node. 
+         */
+        attr = cur->properties;
+        while (attr != NULL) {
+            /* check that attribute is visible */
+            if (xmlC14NIsVisible(ctx, attr, cur)) {
+                xmlListInsert(list, attr);
+            }
+            attr = attr->next;
+        }
+
+        /* do nothing special for xml attributes */
+        break;
+    case XML_C14N_1_1:
+        /* The processing of an element node E MUST be modified slightly when an XPath node-set is 
+         * given as input and some of the element's ancestors are omitted from the node-set. 
+         *
+         * Simple inheritable attributes are attributes that have a value that requires at most a simple 
+         * redeclaration. This redeclaration is done by supplying a new value in the child axis. The 
+         * redeclaration of a simple inheritable attribute A contained in one of E's ancestors is done 
+         * by supplying a value to an attribute Ae inside E with the same name. Simple inheritable attributes 
+         * are xml:lang and xml:space.
+         * 
+         * The method for processing the attribute axis of an element E in the node-set is hence enhanced. 
+         * All element nodes along E's ancestor axis are examined for the nearest occurrences of simple 
+         * inheritable attributes in the xml namespace, such as xml:lang and xml:space (whether or not they 
+         * are in the node-set). From this list of attributes, any simple inheritable attributes that are 
+         * already in E's attribute axis (whether or not they are in the node-set) are removed. Then, 
+         * lexicographically merge this attribute list with the nodes of E's attribute axis that are in 
+         * the node-set. The result of visiting the attribute axis is computed by processing the attribute 
+         * nodes in this merged attribute list.
+         * 
+         * The xml:id attribute is not a simple inheritable attribute and no processing of these attributes is 
+         * performed.
+         * 
+         * The xml:base attribute is not a simple inheritable attribute and requires special processing beyond 
+         * a simple redeclaration.
+         * 
+         * Attributes in the XML namespace other than xml:base, xml:id, xml:lang, and xml:space MUST be processed 
+         * as ordinary attributes.
+         */
+
+        /* 
+         * Add all visible attributes from current node. 
+         */
+        attr = cur->properties;
+        while (attr != NULL) {
+            /* special processing for XML attribute kiks in only when we have invisible parents */
+            if ((!parent_visible) || (xmlC14NIsXmlAttr(attr) == 0)) {
+                /* check that attribute is visible */
+                if (xmlC14NIsVisible(ctx, attr, cur)) {
+                    xmlListInsert(list, attr);
+                }
+            } else {
+                int matched = 0;
+
+                /* check for simple inheritance attributes */
+                if((!matched) && (xml_lang_attr == NULL) && xmlStrEqual(attr->name, BAD_CAST "lang")) {
+                    xml_lang_attr = attr;
+                    matched = 1;
+                } 
+                if((!matched) && (xml_space_attr == NULL) && xmlStrEqual(attr->name, BAD_CAST "space")) {
+                    xml_space_attr = attr;
+                    matched = 1;
+                }
+
+                /* check for base attr */
+                if((!matched) && (xml_base_attr == NULL) && xmlStrEqual(attr->name, BAD_CAST "base")) {
+                    xml_base_attr = attr;
+                    matched = 1;
+                }
+
+                /* otherwise, it is a normal attribute, so just check if it is visible */
+                if((!matched) && xmlC14NIsVisible(ctx, attr, cur)) {
+                    xmlListInsert(list, attr);
+                }
+            }
+         
+            /* move to the next one */
+            attr = attr->next;
+        }
+            
+        /* special processing for XML attribute kiks in only when we have invisible parents */
+        if ((parent_visible)) {
+
+            /* simple inheritance attributes - copy */
+            if(xml_lang_attr == NULL) {
+                xml_lang_attr = xmlC14NFindHiddenParentAttr(ctx, cur->parent, BAD_CAST "lang", XML_XML_NAMESPACE);
+            }
+            if(xml_lang_attr != NULL) {
+                xmlListInsert(list, xml_lang_attr);
+            }
+            if(xml_space_attr == NULL) {
+                xml_space_attr = xmlC14NFindHiddenParentAttr(ctx, cur->parent, BAD_CAST "space", XML_XML_NAMESPACE);
+            }
+            if(xml_space_attr != NULL) {
+                xmlListInsert(list, xml_space_attr);
+            }
+
+            /* base uri attribute - fix up */
+            if(xml_base_attr == NULL) {
+                /* if we don't have base uri attribute, check if we have a "hidden" one above */
+                xml_base_attr = xmlC14NFindHiddenParentAttr(ctx, cur->parent, BAD_CAST "base", XML_XML_NAMESPACE);
+            }
+            if(xml_base_attr != NULL) {
+                xml_base_attr = xmlC14NFixupBaseAttr(ctx, xml_base_attr);
+                if(xml_base_attr != NULL) {                    
+                    xmlListInsert(list, xml_base_attr);
+
+                    /* note that we MUST delete returned attr node ourselves! */
+                    xml_base_attr->next = attrs_to_delete;
+                    attrs_to_delete = xml_base_attr;
+                }
+            }
+        }
+
+        /* done */
+        break;
     }
 
     /* 
@@ -1040,6 +1333,7 @@
     /* 
      * Cleanup
      */
+    xmlFreePropList(attrs_to_delete);
     xmlListDelete(list);
     return (0);
 }
@@ -1096,6 +1390,8 @@
  * xmlC14NProcessElementNode:
  * @ctx: 		the pointer to C14N context object
  * @cur:		the node to process
+ * @visible:    this node is visible
+ * @all_parents_visible: whether all the parents of this node are visible
  *  		
  * Canonical XML v 1.0 (http://www.w3.org/TR/xml-c14n)
  *
@@ -1159,7 +1455,7 @@
         xmlOutputBufferWriteString(ctx->buf, (const char *) cur->name);
     }
 
-    if (!ctx->exclusive) {
+    if (!xmlC14NIsExclusive(ctx)) {
         ret = xmlC14NProcessNamespacesAxis(ctx, cur, visible);
     } else {
         ret = xmlExcC14NProcessNamespacesAxis(ctx, cur, visible);
@@ -1457,9 +1753,10 @@
  *			or not
  * @user_data: 		the first parameter for @is_visible_callback function
  *			(in most cases, it is nodes set)
+ * @mode:   the c14n mode (see @xmlC14NMode)
  * @inclusive_ns_prefixe the list of inclusive namespace prefixes 
  *			ended with a NULL or NULL if there is no
- *			inclusive namespaces (only for exclusive 
+ *			inclusive namespaces (only for ` 
  *			canonicalization)
  * @with_comments: 	include comments in the result (!=0) or not (==0)
  * @buf: 		the output buffer to store canonical XML; this 
@@ -1473,7 +1770,7 @@
 static xmlC14NCtxPtr
 xmlC14NNewCtx(xmlDocPtr doc,  
 	      xmlC14NIsVisibleCallback is_visible_callback, void* user_data,
-              int exclusive, xmlChar ** inclusive_ns_prefixes,
+              xmlC14NMode mode, xmlChar ** inclusive_ns_prefixes,
               int with_comments, xmlOutputBufferPtr buf)
 {
     xmlC14NCtxPtr ctx = NULL;
@@ -1531,11 +1828,11 @@
     }
 
     /*
-     * Set "exclusive" flag, create a nodes set for namespaces
-     * stack and remember list of incluseve prefixes
+     * Set "mode" flag and remember list of incluseve prefixes
+     * for exclusive c14n
      */
-    if (exclusive) {
-        ctx->exclusive = 1;
+    ctx->mode = mode;
+    if(xmlC14NIsExclusive(ctx)) {
         ctx->inclusive_ns_prefixes = inclusive_ns_prefixes;
     }
     return (ctx);
@@ -1548,8 +1845,7 @@
  *			or not
  * @user_data: 		the first parameter for @is_visible_callback function
  *			(in most cases, it is nodes set)
- * @exclusive:		the exclusive flag (0 - non-exclusive canonicalization;
- *			otherwise - exclusive canonicalization)
+ * @mode:	the c14n mode (see @xmlC14NMode)
  * @inclusive_ns_prefixes: the list of inclusive namespace prefixes 
  *			ended with a NULL or NULL if there is no
  *			inclusive namespaces (only for exclusive 
@@ -1567,10 +1863,11 @@
  */
 int 		
 xmlC14NExecute(xmlDocPtr doc, xmlC14NIsVisibleCallback is_visible_callback,
-	 void* user_data, int exclusive, xmlChar **inclusive_ns_prefixes,
+	 void* user_data, int mode, xmlChar **inclusive_ns_prefixes,
 	 int with_comments, xmlOutputBufferPtr buf) {
 
     xmlC14NCtxPtr ctx;
+    xmlC14NMode c14n_mode = XML_C14N_1_0;
     int ret;
 
     if ((buf == NULL) || (doc == NULL)) {
@@ -1578,6 +1875,19 @@
         return (-1);
     }
 
+    /* for backward compatibility, we have to have "mode" as "int" 
+       and here we check that user gives valid value */
+    switch(mode) {
+    case XML_C14N_1_0:
+    case XML_C14N_EXCLUSIVE_1_0:
+    case XML_C14N_1_1: 
+         c14n_mode = (xmlC14NMode)mode;
+         break;
+    default:       
+        xmlC14NErrParam("invalid mode for executing c14n");
+        return (-1);
+    }
+
     /*
      *  Validate the encoding output buffer encoding
      */
@@ -1588,8 +1898,8 @@
     }
 
     ctx = xmlC14NNewCtx(doc, is_visible_callback, user_data, 
-			exclusive, inclusive_ns_prefixes,
-                        with_comments, buf);
+	            c14n_mode, inclusive_ns_prefixes,
+                    with_comments, buf);
     if (ctx == NULL) {
         xmlC14NErr(NULL, (xmlNodePtr) doc, XML_C14N_CREATE_CTXT,
 		   "xmlC14NExecute: unable to create C14N context\n");
@@ -1637,8 +1947,7 @@
  * @doc: 		the XML document for canonization
  * @nodes: 		the nodes set to be included in the canonized image
  *      		or NULL if all document nodes should be included
- * @exclusive:		the exclusive flag (0 - non-exclusive canonicalization;
- *			otherwise - exclusive canonicalization)
+ * @mode:		the c14n mode (see @xmlC14NMode)
  * @inclusive_ns_prefixes: the list of inclusive namespace prefixes 
  *			ended with a NULL or NULL if there is no
  *			inclusive namespaces (only for exclusive 
@@ -1656,12 +1965,12 @@
  */
 int
 xmlC14NDocSaveTo(xmlDocPtr doc, xmlNodeSetPtr nodes,
-                 int exclusive, xmlChar ** inclusive_ns_prefixes,
+                 int mode, xmlChar ** inclusive_ns_prefixes,
                  int with_comments, xmlOutputBufferPtr buf) {
     return(xmlC14NExecute(doc, 
 			(xmlC14NIsVisibleCallback)xmlC14NIsNodeInNodeset,
 			nodes,
-			exclusive,
+			mode,
 			inclusive_ns_prefixes,
 			with_comments,
 			buf));
@@ -1673,8 +1982,7 @@
  * @doc: 		the XML document for canonization
  * @nodes: 		the nodes set to be included in the canonized image
  *      		or NULL if all document nodes should be included
- * @exclusive:		the exclusive flag (0 - non-exclusive canonicalization;
- *			otherwise - exclusive canonicalization)
+ * @mode:		the c14n mode (see @xmlC14NMode)
  * @inclusive_ns_prefixes: the list of inclusive namespace prefixes 
  *			ended with a NULL or NULL if there is no
  *			inclusive namespaces (only for exclusive 
@@ -1692,7 +2000,7 @@
  */
 int
 xmlC14NDocDumpMemory(xmlDocPtr doc, xmlNodeSetPtr nodes,
-                     int exclusive, xmlChar ** inclusive_ns_prefixes,
+                     int mode, xmlChar ** inclusive_ns_prefixes,
                      int with_comments, xmlChar ** doc_txt_ptr)
 {
     int ret;
@@ -1717,7 +2025,7 @@
     /*
      * canonize document and write to buffer
      */
-    ret = xmlC14NDocSaveTo(doc, nodes, exclusive, inclusive_ns_prefixes,
+    ret = xmlC14NDocSaveTo(doc, nodes, mode, inclusive_ns_prefixes,
                            with_comments, buf);
     if (ret < 0) {
         xmlC14NErrInternal("saving doc to output buffer");
@@ -1743,8 +2051,7 @@
  * @doc: 		the XML document for canonization
  * @nodes: 		the nodes set to be included in the canonized image
  *      		or NULL if all document nodes should be included
- * @exclusive:		the exclusive flag (0 - non-exclusive canonicalization;
- *			otherwise - exclusive canonicalization)
+ * @mode:		the c14n mode (see @xmlC14NMode)
  * @inclusive_ns_prefixes: the list of inclusive namespace prefixes 
  *			ended with a NULL or NULL if there is no
  *			inclusive namespaces (only for exclusive 
@@ -1764,7 +2071,7 @@
  */
 int
 xmlC14NDocSave(xmlDocPtr doc, xmlNodeSetPtr nodes,
-               int exclusive, xmlChar ** inclusive_ns_prefixes,
+               int mode, xmlChar ** inclusive_ns_prefixes,
                int with_comments, const char *filename, int compression)
 {
     xmlOutputBufferPtr buf;
@@ -1791,7 +2098,7 @@
     /*
      * canonize document and write to buffer
      */
-    ret = xmlC14NDocSaveTo(doc, nodes, exclusive, inclusive_ns_prefixes,
+    ret = xmlC14NDocSaveTo(doc, nodes, mode, inclusive_ns_prefixes,
                            with_comments, buf);
     if (ret < 0) {
         xmlC14NErrInternal("cannicanize document to buffer");
@@ -1919,7 +2226,7 @@
         }
         cur++;
     }
-    *out++ = 0;
+    *out = 0;
     return (buffer);
 }
 #endif /* LIBXML_OUTPUT_ENABLED */
diff --git a/catalog.c b/catalog.c
index af84b7c..f33a0aa 100644
--- a/catalog.c
+++ b/catalog.c
@@ -997,18 +997,15 @@
     }
 #ifdef HAVE_STAT
     len = read(fd, content, size);
+    close(fd);
 #else
     len = fread(content, 1, size, fd);
+    fclose(fd);
 #endif
     if (len < 0) {
         xmlFree(content);
         return (NULL);
     }
-#ifdef HAVE_STAT
-    close(fd);
-#else
-    fclose(fd);
-#endif
     content[len] = 0;
 
     return(content);
diff --git a/config.h b/config.h
index d980955..c70d020 100644
--- a/config.h
+++ b/config.h
@@ -1,21 +1,5 @@
 /* config.h.  Generated from config.h.in by configure.  */
 /* config.h.in.  Generated from configure.in by autoheader.  */
-#define PACKAGE "libxml2"
-#define VERSION "2.7.3"
-/* #undef HAVE_LIBZ */
-/* #undef HAVE_LIBM */
-#define HAVE_ISINF 
-#define HAVE_ISNAN 
-/* #undef HAVE_LIBHISTORY */
-/* #undef HAVE_LIBREADLINE */
-/* #undef HAVE_LIBPTHREAD */
-/* #undef HAVE_PTHREAD_H */
-
-/* Define if IPV6 support is there */
-/* #undef SUPPORT_IP6 */
-
-/* Define if getaddrinfo is there */
-/* #undef HAVE_GETADDRINFO */
 
 /* Define to 1 if you have the <ansidecl.h> header file. */
 /* #undef HAVE_ANSIDECL_H */
@@ -42,7 +26,7 @@
 #define HAVE_DLFCN_H 1
 
 /* Have dlopen based dso */
-#define HAVE_DLOPEN 1
+#define HAVE_DLOPEN /**/
 
 /* Define to 1 if you have the <dl.h> header file. */
 /* #undef HAVE_DL_H */
@@ -75,7 +59,7 @@
 #define HAVE_FTIME 1
 
 /* Define if getaddrinfo is there */
-/* #undef HAVE_GETADDRINFO  */
+/* #undef HAVE_GETADDRINFO */
 
 /* Define to 1 if you have the `gettimeofday' function. */
 #define HAVE_GETTIMEOFDAY 1
@@ -90,10 +74,10 @@
 /* #undef HAVE_INTTYPES_H_H */
 
 /* Define if isinf is there */
-#define HAVE_ISINF 
+#define HAVE_ISINF /**/
 
 /* Define if isnan is there */
-#define HAVE_ISNAN 
+#define HAVE_ISNAN /**/
 
 /* Define to 1 if you have the `isnand' function. */
 /* #undef HAVE_ISNAND */
@@ -101,6 +85,9 @@
 /* Define if history library is there (-lhistory) */
 /* #undef HAVE_LIBHISTORY */
 
+/* Have compression library */
+/* #undef HAVE_LIBLZMA */
+
 /* Define if pthread library is there (-lpthread) */
 /* #undef HAVE_LIBPTHREAD */
 
@@ -116,6 +103,9 @@
 /* Define to 1 if you have the `localtime' function. */
 #define HAVE_LOCALTIME 1
 
+/* Define to 1 if you have the <lzma.h> header file. */
+/* #undef HAVE_LZMA_H */
+
 /* Define to 1 if you have the <malloc.h> header file. */
 /* #undef HAVE_MALLOC_H 1 Already defined in AndroidConfig.h */
 
@@ -137,12 +127,18 @@
 /* Define to 1 if you have the <netinet/in.h> header file. */
 #define HAVE_NETINET_IN_H 1
 
+/* Define to 1 if you have the <poll.h> header file. */
+#define HAVE_POLL_H 1
+
 /* Define to 1 if you have the `printf' function. */
 #define HAVE_PRINTF 1
 
 /* Define if <pthread.h> is there */
 /* #undef HAVE_PTHREAD_H */
 
+/* Define to 1 if you have the `rand' function. */
+#define HAVE_RAND 1
+
 /* Define to 1 if you have the <resolv.h> header file. */
 #define HAVE_RESOLV_H 1
 
@@ -161,6 +157,9 @@
 /* Define to 1 if you have the `sprintf' function. */
 #define HAVE_SPRINTF 1
 
+/* Define to 1 if you have the `srand' function. */
+#define HAVE_SRAND 1
+
 /* Define to 1 if you have the `sscanf' function. */
 #define HAVE_SSCANF 1
 
@@ -223,6 +222,9 @@
 /* Define to 1 if you have the <sys/types.h> header file. */
 #define HAVE_SYS_TYPES_H 1
 
+/* Define to 1 if you have the `time' function. */
+#define HAVE_TIME 1
+
 /* Define to 1 if you have the <time.h> header file. */
 #define HAVE_TIME_H 1
 
@@ -253,6 +255,10 @@
 /* Define as const if the declaration of iconv() needs const. */
 /* #undef ICONV_CONST */
 
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#define LT_OBJDIR ".libs/"
+
 /* Name of package */
 #define PACKAGE "libxml2"
 
@@ -268,6 +274,9 @@
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME ""
 
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
 /* Define to the version of this package. */
 #define PACKAGE_VERSION ""
 
@@ -281,7 +290,7 @@
 /* #undef SUPPORT_IP6 */
 
 /* Version number of package */
-#define VERSION "2.7.3"
+#define VERSION "2.7.8"
 
 /* Determine what socket length (socklen_t) data type is */
 #define XML_SOCKLEN_T socklen_t
diff --git a/debugXML.c b/debugXML.c
index b56651b..c26217a 100644
--- a/debugXML.c
+++ b/debugXML.c
@@ -259,7 +259,9 @@
 			 "Name is not an NCName '%s'", (const char *) name);
 	}
 	if ((ctxt->dict != NULL) &&
-	    (!xmlDictOwns(ctxt->dict, name))) {
+	    (!xmlDictOwns(ctxt->dict, name)) &&
+            ((ctxt->doc == NULL) ||
+             ((ctxt->doc->parseFlags & (XML_PARSE_SAX1 | XML_PARSE_NODICT)) == 0))) {
 	    xmlDebugErr3(ctxt, XML_CHECK_OUTSIDE_DICT,
 			 "Name is not from the document dictionnary '%s'",
 			 (const char *) name);
@@ -2801,7 +2803,6 @@
 {
     char prompt[500] = "/ > ";
     char *cmdline = NULL, *cur;
-    int nbargs;
     char command[100];
     char arg[400];
     int i;
@@ -2853,7 +2854,6 @@
          * Parse the command itself
          */
         cur = cmdline;
-        nbargs = 0;
         while ((*cur == ' ') || (*cur == '\t'))
             cur++;
         i = 0;
@@ -2866,7 +2866,6 @@
         command[i] = 0;
         if (i == 0)
             continue;
-        nbargs++;
 
         /*
          * Parse the argument
@@ -2880,8 +2879,6 @@
             arg[i++] = *cur++;
         }
         arg[i] = 0;
-        if (i != 0)
-            nbargs++;
 
         /*
          * start interpreting the command
@@ -2944,7 +2941,7 @@
 		xmlGenericError(xmlGenericErrorContext,
                         "Write command requires a filename argument\n");
 	    else
-		xmlShellWrite(ctxt, arg, NULL, NULL);
+		xmlShellWrite(ctxt, arg, ctxt->node, NULL);
 #endif /* LIBXML_OUTPUT_ENABLED */
         } else if (!strcmp(command, "grep")) {
             xmlShellGrep(ctxt, arg, ctxt->node, NULL);
diff --git a/dict.c b/dict.c
index 0e07e8d..ae4966b 100644
--- a/dict.c
+++ b/dict.c
@@ -2,7 +2,7 @@
  * dict.c: dictionary of reusable strings, just used to avoid allocation
  *         and freeing operations.
  *
- * Copyright (C) 2003 Daniel Veillard.
+ * Copyright (C) 2003-2012 Daniel Veillard.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -19,6 +19,28 @@
 #define IN_LIBXML
 #include "libxml.h"
 
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+/*
+ * Following http://www.ocert.org/advisories/ocert-2011-003.html
+ * it seems that having hash randomization might be a good idea
+ * when using XML with untrusted data
+ * Note1: that it works correctly only if compiled with WITH_BIG_KEY
+ *  which is the default.
+ * Note2: the fast function used for a small dict won't protect very
+ *  well but since the attack is based on growing a very big hash
+ *  list we will use the BigKey algo as soon as the hash size grows
+ *  over MIN_DICT_SIZE so this actually works
+ */
+#if defined(HAVE_RAND) && defined(HAVE_SRAND) && defined(HAVE_TIME)
+#define DICT_RANDOMIZATION
+#endif
+
 #include <string.h>
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
@@ -44,23 +66,23 @@
 #define WITH_BIG_KEY
 
 #ifdef WITH_BIG_KEY
-#define xmlDictComputeKey(dict, name, len)			\
-    (((dict)->size == MIN_DICT_SIZE) ?				\
-     xmlDictComputeFastKey(name, len) :				\
-     xmlDictComputeBigKey(name, len))
+#define xmlDictComputeKey(dict, name, len)                              \
+    (((dict)->size == MIN_DICT_SIZE) ?                                  \
+     xmlDictComputeFastKey(name, len, (dict)->seed) :                   \
+     xmlDictComputeBigKey(name, len, (dict)->seed))
 
-#define xmlDictComputeQKey(dict, prefix, plen, name, len)	\
-    (((prefix) == NULL) ?					\
-      (xmlDictComputeKey(dict, name, len)) :			\
-      (((dict)->size == MIN_DICT_SIZE) ?			\
-       xmlDictComputeFastQKey(prefix, plen, name, len) :	\
-       xmlDictComputeBigQKey(prefix, plen, name, len)))
+#define xmlDictComputeQKey(dict, prefix, plen, name, len)               \
+    (((prefix) == NULL) ?                                               \
+      (xmlDictComputeKey(dict, name, len)) :                             \
+      (((dict)->size == MIN_DICT_SIZE) ?                                \
+       xmlDictComputeFastQKey(prefix, plen, name, len, (dict)->seed) :	\
+       xmlDictComputeBigQKey(prefix, plen, name, len, (dict)->seed)))
 
 #else /* !WITH_BIG_KEY */
-#define xmlDictComputeKey(dict, name, len)			\
-        xmlDictComputeFastKey(name, len)
-#define xmlDictComputeQKey(dict, prefix, plen, name, len)	\
-        xmlDictComputeFastQKey(prefix, plen, name, len)
+#define xmlDictComputeKey(dict, name, len)                              \
+        xmlDictComputeFastKey(name, len, (dict)->seed)
+#define xmlDictComputeQKey(dict, prefix, plen, name, len)               \
+        xmlDictComputeFastQKey(prefix, plen, name, len, (dict)->seed)
 #endif /* WITH_BIG_KEY */
 
 /*
@@ -98,6 +120,8 @@
     xmlDictStringsPtr strings;
 
     struct _xmlDict *subdict;
+    /* used for randomization */
+    int seed;
 };
 
 /*
@@ -125,6 +149,9 @@
     if ((xmlDictMutex = xmlNewRMutex()) == NULL)
         return(0);
 
+#ifdef DICT_RANDOMIZATION
+    srand(time(NULL));
+#endif
     xmlDictInitialized = 1;
     return(1);
 }
@@ -277,13 +304,13 @@
  */
 
 static uint32_t
-xmlDictComputeBigKey(const xmlChar* data, int namelen) {
+xmlDictComputeBigKey(const xmlChar* data, int namelen, int seed) {
     uint32_t hash;
     int i;
 
     if (namelen <= 0 || data == NULL) return(0);
 
-    hash = 0;
+    hash = seed;
 
     for (i = 0;i < namelen; i++) {
         hash += data[i];
@@ -310,12 +337,12 @@
  */
 static unsigned long
 xmlDictComputeBigQKey(const xmlChar *prefix, int plen,
-                      const xmlChar *name, int len)
+                      const xmlChar *name, int len, int seed)
 {
     uint32_t hash;
     int i;
 
-    hash = 0;
+    hash = seed;
 
     for (i = 0;i < plen; i++) {
         hash += prefix[i];
@@ -346,8 +373,8 @@
  * for low hash table fill.
  */
 static unsigned long
-xmlDictComputeFastKey(const xmlChar *name, int namelen) {
-    unsigned long value = 0L;
+xmlDictComputeFastKey(const xmlChar *name, int namelen, int seed) {
+    unsigned long value = seed;
 
     if (name == NULL) return(0);
     value = *name;
@@ -381,9 +408,9 @@
  */
 static unsigned long
 xmlDictComputeFastQKey(const xmlChar *prefix, int plen,
-                       const xmlChar *name, int len)
+                       const xmlChar *name, int len, int seed)
 {
-    unsigned long value = 0L;
+    unsigned long value = (unsigned long) seed;
 
     if (plen == 0)
 	value += 30 * (unsigned long) ':';
@@ -460,6 +487,11 @@
 	dict->subdict = NULL;
         if (dict->dict) {
 	    memset(dict->dict, 0, MIN_DICT_SIZE * sizeof(xmlDictEntry));
+#ifdef DICT_RANDOMIZATION
+            dict->seed = rand();
+#else
+            dict->seed = 0;
+#endif
 	    return(dict);
         }
         xmlFree(dict);
@@ -486,6 +518,7 @@
 #ifdef DICT_DEBUG_PATTERNS
         fprintf(stderr, "R");
 #endif
+        dict->seed = sub->seed;
         dict->subdict = sub;
 	xmlDictReference(dict->subdict);
     }
@@ -698,7 +731,6 @@
 		inside_dict = 0;
 		iter = next;
 	    }
-	    inside_dict = 0;
 	}
 	xmlFree(dict->dict);
     }
diff --git a/elfgcchack.h b/elfgcchack.h
index 14cad6d..84e8151 100644
--- a/elfgcchack.h
+++ b/elfgcchack.h
@@ -15491,6 +15491,18 @@
 
 #if defined(LIBXML_XINCLUDE_ENABLED)
 #ifdef bottom_xinclude
+#undef xmlXIncludeProcessTreeFlagsData
+extern __typeof (xmlXIncludeProcessTreeFlagsData) xmlXIncludeProcessTreeFlagsData __attribute((alias("xmlXIncludeProcessTreeFlagsData__internal_alias")));
+#else
+#ifndef xmlXIncludeProcessTreeFlagsData
+extern __typeof (xmlXIncludeProcessTreeFlagsData) xmlXIncludeProcessTreeFlagsData__internal_alias __attribute((visibility("hidden")));
+#define xmlXIncludeProcessTreeFlagsData xmlXIncludeProcessTreeFlagsData__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XINCLUDE_ENABLED)
+#ifdef bottom_xinclude
 #undef xmlXIncludeSetFlags
 extern __typeof (xmlXIncludeSetFlags) xmlXIncludeSetFlags __attribute((alias("xmlXIncludeSetFlags__internal_alias")));
 #else
diff --git a/encoding.c b/encoding.c
index 2abc32e..fb0c38a 100644
--- a/encoding.c
+++ b/encoding.c
@@ -1,7 +1,7 @@
 /*
  * encoding.c : implements the encoding conversion functions needed for XML
  *
- * Related specs: 
+ * 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
@@ -98,7 +98,7 @@
 }
 
 #ifdef LIBXML_ICU_ENABLED
-static uconv_t* 
+static uconv_t*
 openIcuConverter(const char* name, int toUnicode)
 {
   UErrorCode status = U_ZERO_ERROR;
@@ -112,11 +112,11 @@
 
   status = U_ZERO_ERROR;
   if (toUnicode) {
-    ucnv_setToUCallBack(conv->uconv, UCNV_TO_U_CALLBACK_STOP, 
+    ucnv_setToUCallBack(conv->uconv, UCNV_TO_U_CALLBACK_STOP,
                         NULL, NULL, NULL, &status);
   }
   else {
-    ucnv_setFromUCallBack(conv->uconv, UCNV_FROM_U_CALLBACK_STOP, 
+    ucnv_setFromUCallBack(conv->uconv, UCNV_FROM_U_CALLBACK_STOP,
                         NULL, NULL, NULL, &status);
   }
   if (U_FAILURE(status))
@@ -128,7 +128,7 @@
     return conv;
 
 error:
-  if (conv->uconv) 
+  if (conv->uconv)
     ucnv_close(conv->uconv);
   xmlFree(conv);
   return NULL;
@@ -183,12 +183,12 @@
 	    break;
         if (c < 0x80) {
 	    *out++ = c;
-	} else { 
+	} else {
 	    *outlen = out - outstart;
 	    *inlen = processed - base;
 	    return(-1);
 	}
- 
+
 	processed = (const unsigned char*) in;
     }
     *outlen = out - outstart;
@@ -254,7 +254,7 @@
 
 	if (inend - in < trailing) {
 	    break;
-	} 
+	}
 
 	for ( ; trailing; trailing--) {
 	    if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))
@@ -311,19 +311,19 @@
     outend = out + *outlen;
     inend = in + (*inlen);
     instop = inend;
-    
-    while (in < inend && out < outend - 1) {
-    	if (*in >= 0x80) {
+
+    while ((in < inend) && (out < outend - 1)) {
+	if (*in >= 0x80) {
 	    *out++ = (((*in) >>  6) & 0x1F) | 0xC0;
-        *out++ = ((*in) & 0x3F) | 0x80;
+            *out++ = ((*in) & 0x3F) | 0x80;
 	    ++in;
 	}
-	if (instop - in > outend - out) instop = in + (outend - out); 
-	while (in < instop && *in < 0x80) {
+	if ((instop - in) > (outend - out)) instop = in + (outend - out);
+	while ((in < instop) && (*in < 0x80)) {
 	    *out++ = *in++;
 	}
-    }	
-    if (in < inend && out < outend && *in < 0x80) {
+    }
+    if ((in < inend) && (out < outend) && (*in < 0x80)) {
         *out++ = *in++;
     }
     *outlen = out - outstart;
@@ -427,7 +427,7 @@
 
 	if (inend - in < trailing) {
 	    break;
-	} 
+	}
 
 	for ( ; trailing; trailing--) {
 	    if (in >= inend)
@@ -535,7 +535,7 @@
         else if (c <   0x800) {  *out++= ((c >>  6) & 0x1F) | 0xC0;  bits=  0; }
         else if (c < 0x10000) {  *out++= ((c >> 12) & 0x0F) | 0xE0;  bits=  6; }
         else                  {  *out++= ((c >> 18) & 0x07) | 0xF0;  bits= 12; }
- 
+
         for ( ; bits >= 0; bits-= 6) {
             if (out >= outend)
 	        break;
@@ -560,7 +560,7 @@
  * block of chars out.
  *
  * Returns the number of bytes written, or -1 if lack of space, or -2
- *     if the transcoding failed. 
+ *     if the transcoding failed.
  */
 static int
 UTF8ToUTF16LE(unsigned char* outb, int *outlen,
@@ -606,7 +606,7 @@
 
       if (inend - in < trailing) {
           break;
-      } 
+      }
 
       for ( ; trailing; trailing--) {
           if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))
@@ -669,7 +669,7 @@
  * block of chars out.
  *
  * Returns the number of bytes written, or -1 if lack of space, or -2
- *     if the transcoding failed. 
+ *     if the transcoding failed.
  */
 static int
 UTF8ToUTF16(unsigned char* outb, int *outlen,
@@ -741,7 +741,7 @@
 	    in++;
 	} else {
 	    c= *in++;
-	} 
+	}
         if ((c & 0xFC00) == 0xD800) {    /* surrogates */
 	    if (in >= inend) {           /* (in > inend) shouldn't happens */
 		*outlen = out - outstart;
@@ -771,15 +771,15 @@
         }
 
 	/* assertion: c is a single UTF-4 value */
-        if (out >= outend) 
+        if (out >= outend)
 	    break;
         if      (c <    0x80) {  *out++=  c;                bits= -6; }
         else if (c <   0x800) {  *out++= ((c >>  6) & 0x1F) | 0xC0;  bits=  0; }
         else if (c < 0x10000) {  *out++= ((c >> 12) & 0x0F) | 0xE0;  bits=  6; }
         else                  {  *out++= ((c >> 18) & 0x07) | 0xF0;  bits= 12; }
- 
+
         for ( ; bits >= 0; bits-= 6) {
-            if (out >= outend) 
+            if (out >= outend)
 	        break;
             *out++= ((c >> bits) & 0x3F) | 0x80;
         }
@@ -802,7 +802,7 @@
  * block of chars out.
  *
  * Returns the number of byte written, or -1 by lack of space, or -2
- *     if the transcoding failed. 
+ *     if the transcoding failed.
  */
 static int
 UTF8ToUTF16BE(unsigned char* outb, int *outlen,
@@ -848,7 +848,7 @@
 
       if (inend - in < trailing) {
           break;
-      } 
+      }
 
       for ( ; trailing; trailing--) {
           if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))  break;
@@ -912,13 +912,13 @@
  *
  * Guess the encoding of the entity using the first bytes of the entity content
  * according to the non-normative appendix F of the XML-1.0 recommendation.
- * 
+ *
  * Returns one of the XML_CHAR_ENCODING_... values.
  */
 xmlCharEncoding
 xmlDetectCharEncoding(const unsigned char* in, int len)
 {
-    if (in == NULL) 
+    if (in == NULL)
         return(XML_CHAR_ENCODING_NONE);
     if (len >= 4) {
 	if ((in[0] == 0x00) && (in[1] == 0x00) &&
@@ -999,7 +999,7 @@
  * @alias:  the alias name as parsed, in UTF-8 format (ASCII actually)
  *
  * Lookup an encoding name for the given alias.
- * 
+ *
  * Returns NULL if not found, otherwise the original name
  */
 const char *
@@ -1037,7 +1037,7 @@
  *
  * Registers an alias @alias for an encoding named @name. Existing alias
  * will be overwritten.
- * 
+ *
  * Returns 0 in case of success, -1 in case of error
  */
 int
@@ -1057,13 +1057,13 @@
     if (xmlCharEncodingAliases == NULL) {
 	xmlCharEncodingAliasesNb = 0;
 	xmlCharEncodingAliasesMax = 20;
-	xmlCharEncodingAliases = (xmlCharEncodingAliasPtr) 
+	xmlCharEncodingAliases = (xmlCharEncodingAliasPtr)
 	      xmlMalloc(xmlCharEncodingAliasesMax * sizeof(xmlCharEncodingAlias));
 	if (xmlCharEncodingAliases == NULL)
 	    return(-1);
     } else if (xmlCharEncodingAliasesNb >= xmlCharEncodingAliasesMax) {
 	xmlCharEncodingAliasesMax *= 2;
-	xmlCharEncodingAliases = (xmlCharEncodingAliasPtr) 
+	xmlCharEncodingAliases = (xmlCharEncodingAliasPtr)
 	      xmlRealloc(xmlCharEncodingAliases,
 		         xmlCharEncodingAliasesMax * sizeof(xmlCharEncodingAlias));
     }
@@ -1094,7 +1094,7 @@
  * @alias:  the alias name as parsed, in UTF-8 format (ASCII actually)
  *
  * Unregisters an encoding alias @alias
- * 
+ *
  * Returns 0 in case of success, -1 in case of error
  */
 int
@@ -1129,7 +1129,7 @@
  * Compare the string to the encoding schemes already known. Note
  * that the comparison is case insensitive accordingly to the section
  * [XML] 4.3.3 Character Encoding in Entities.
- * 
+ *
  * Returns one of the XML_CHAR_ENCODING_... values or XML_CHAR_ENCODING_NONE
  * if not recognized.
  */
@@ -1166,7 +1166,7 @@
      */
     if (!strcmp(upper, "UTF-16")) return(XML_CHAR_ENCODING_UTF16LE);
     if (!strcmp(upper, "UTF16")) return(XML_CHAR_ENCODING_UTF16LE);
-    
+
     if (!strcmp(upper, "ISO-10646-UCS-2")) return(XML_CHAR_ENCODING_UCS2);
     if (!strcmp(upper, "UCS-2")) return(XML_CHAR_ENCODING_UCS2);
     if (!strcmp(upper, "UCS2")) return(XML_CHAR_ENCODING_UCS2);
@@ -1179,7 +1179,7 @@
     if (!strcmp(upper, "UCS-4")) return(XML_CHAR_ENCODING_UCS4LE);
     if (!strcmp(upper, "UCS4")) return(XML_CHAR_ENCODING_UCS4LE);
 
-    
+
     if (!strcmp(upper,  "ISO-8859-1")) return(XML_CHAR_ENCODING_8859_1);
     if (!strcmp(upper,  "ISO-LATIN-1")) return(XML_CHAR_ENCODING_8859_1);
     if (!strcmp(upper,  "ISO LATIN 1")) return(XML_CHAR_ENCODING_8859_1);
@@ -1302,7 +1302,7 @@
  * Returns the xmlCharEncodingHandlerPtr created (or NULL in case of error).
  */
 xmlCharEncodingHandlerPtr
-xmlNewCharEncodingHandler(const char *name, 
+xmlNewCharEncodingHandler(const char *name,
                           xmlCharEncodingInputFunc input,
                           xmlCharEncodingOutputFunc output) {
     xmlCharEncodingHandlerPtr handler;
@@ -1347,6 +1347,7 @@
         xmlEncodingErrMemory("xmlNewCharEncodingHandler : out of memory !\n");
 	return(NULL);
     }
+    memset(handler, 0, sizeof(xmlCharEncodingHandler));
     handler->input = input;
     handler->output = output;
     handler->name = up;
@@ -1382,7 +1383,7 @@
 void
 xmlInitCharEncodingHandlers(void) {
     unsigned short int tst = 0x1234;
-    unsigned char *ptr = (unsigned char *) &tst; 
+    unsigned char *ptr = (unsigned char *) &tst;
 
     if (handlers != NULL) return;
 
@@ -1402,9 +1403,9 @@
     }
     xmlNewCharEncodingHandler("UTF-8", UTF8ToUTF8, UTF8ToUTF8);
 #ifdef LIBXML_OUTPUT_ENABLED
-    xmlUTF16LEHandler = 
+    xmlUTF16LEHandler =
           xmlNewCharEncodingHandler("UTF-16LE", UTF16LEToUTF8, UTF8ToUTF16LE);
-    xmlUTF16BEHandler = 
+    xmlUTF16BEHandler =
           xmlNewCharEncodingHandler("UTF-16BE", UTF16BEToUTF8, UTF8ToUTF16BE);
     xmlNewCharEncodingHandler("UTF-16", UTF16LEToUTF8, UTF8ToUTF16);
     xmlNewCharEncodingHandler("ISO-8859-1", isolat1ToUTF8, UTF8Toisolat1);
@@ -1414,9 +1415,9 @@
     xmlNewCharEncodingHandler("HTML", NULL, UTF8ToHtml);
 #endif
 #else
-    xmlUTF16LEHandler = 
+    xmlUTF16LEHandler =
           xmlNewCharEncodingHandler("UTF-16LE", UTF16LEToUTF8, NULL);
-    xmlUTF16BEHandler = 
+    xmlUTF16BEHandler =
           xmlNewCharEncodingHandler("UTF-16BE", UTF16BEToUTF8, NULL);
     xmlNewCharEncodingHandler("UTF-16", UTF16LEToUTF8, NULL);
     xmlNewCharEncodingHandler("ISO-8859-1", isolat1ToUTF8, NULL);
@@ -1466,7 +1467,7 @@
 void
 xmlRegisterCharEncodingHandler(xmlCharEncodingHandlerPtr handler) {
     if (handlers == NULL) xmlInitCharEncodingHandlers();
-    if (handler == NULL) {
+    if ((handler == NULL) || (handlers == NULL)) {
         xmlEncodingErr(XML_I18N_NO_HANDLER,
 		"xmlRegisterCharEncodingHandler: NULL handler !\n", NULL);
 	return;
@@ -1510,6 +1511,8 @@
             if (handler != NULL) return(handler);
             handler = xmlFindCharEncodingHandler("ebcdic");
             if (handler != NULL) return(handler);
+            handler = xmlFindCharEncodingHandler("EBCDIC-US");
+            if (handler != NULL) return(handler);
 	    break;
         case XML_CHAR_ENCODING_UCS4BE:
             handler = xmlFindCharEncodingHandler("ISO-10646-UCS-4");
@@ -1600,10 +1603,10 @@
             handler = xmlFindCharEncodingHandler("EUC-JP");
             if (handler != NULL) return(handler);
 	    break;
-	default: 
+	default:
 	    break;
     }
-    
+
 #ifdef DEBUG_ENCODING
     xmlGenericError(xmlGenericErrorContext,
 	    "No handler found for encoding %d\n", enc);
@@ -1629,7 +1632,7 @@
     iconv_t icv_in, icv_out;
 #endif /* LIBXML_ICONV_ENABLED */
 #ifdef LIBXML_ICU_ENABLED
-    xmlCharEncodingHandlerPtr enc;
+    xmlCharEncodingHandlerPtr encu;
     uconv_t *ucv_in, *ucv_out;
 #endif /* LIBXML_ICU_ENABLED */
     char upper[100];
@@ -1656,14 +1659,17 @@
     }
     upper[i] = 0;
 
-    for (i = 0;i < nbCharEncodingHandler; i++)
-        if (!strcmp(upper, handlers[i]->name)) {
+    if (handlers != NULL) {
+        for (i = 0;i < nbCharEncodingHandler; i++) {
+            if (!strcmp(upper, handlers[i]->name)) {
 #ifdef DEBUG_ENCODING
-            xmlGenericError(xmlGenericErrorContext,
-		    "Found registered handler for encoding %s\n", name);
+                xmlGenericError(xmlGenericErrorContext,
+                        "Found registered handler for encoding %s\n", name);
 #endif
-	    return(handlers[i]);
-	}
+                return(handlers[i]);
+            }
+        }
+    }
 
 #ifdef LIBXML_ICONV_ENABLED
     /* check whether iconv can handle this */
@@ -1683,6 +1689,7 @@
 	        iconv_close(icv_out);
 		return(NULL);
 	    }
+            memset(enc, 0, sizeof(xmlCharEncodingHandler));
 	    enc->name = xmlMemStrdup(name);
 	    enc->input = NULL;
 	    enc->output = NULL;
@@ -1703,23 +1710,24 @@
     ucv_in = openIcuConverter(name, 1);
     ucv_out = openIcuConverter(name, 0);
     if (ucv_in != NULL && ucv_out != NULL) {
-	    enc = (xmlCharEncodingHandlerPtr)
-	          xmlMalloc(sizeof(xmlCharEncodingHandler));
-	    if (enc == NULL) {
+	    encu = (xmlCharEncodingHandlerPtr)
+	           xmlMalloc(sizeof(xmlCharEncodingHandler));
+	    if (encu == NULL) {
                 closeIcuConverter(ucv_in);
                 closeIcuConverter(ucv_out);
 		return(NULL);
 	    }
-	    enc->name = xmlMemStrdup(name);
-	    enc->input = NULL;
-	    enc->output = NULL;
-	    enc->uconv_in = ucv_in;
-	    enc->uconv_out = ucv_out;
+            memset(encu, 0, sizeof(xmlCharEncodingHandler));
+	    encu->name = xmlMemStrdup(name);
+	    encu->input = NULL;
+	    encu->output = NULL;
+	    encu->uconv_in = ucv_in;
+	    encu->uconv_out = ucv_out;
 #ifdef DEBUG_ENCODING
             xmlGenericError(xmlGenericErrorContext,
 		    "Found ICU converter handler for encoding %s\n", name);
 #endif
-	    return enc;
+	    return encu;
     } else if (ucv_in != NULL || ucv_out != NULL) {
             closeIcuConverter(ucv_in);
             closeIcuConverter(ucv_out);
@@ -1764,12 +1772,12 @@
  * @in:  a pointer to an array of ISO Latin 1 chars
  * @inlen:  the length of @in
  *
- * Returns 0 if success, or 
+ * Returns 0 if success, or
  *     -1 by lack of space, or
  *     -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
  *     -3 if there the last byte can't form a single output char.
- *     
+ *
  * The value of @inlen after return is the number of octets consumed
  *     as the return value is positive, else unpredictable.
  * The value of @outlen after return is the number of ocetes consumed.
@@ -1831,12 +1839,12 @@
  * @in:  a pointer to an array of ISO Latin 1 chars
  * @inlen:  the length of @in
  *
- * Returns 0 if success, or 
+ * Returns 0 if success, or
  *     -1 by lack of space, or
  *     -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
  *     -3 if there the last byte can't form a single output char.
- *     
+ *
  * The value of @inlen after return is the number of octets consumed
  *     as the return value is positive, else unpredictable.
  * The value of @outlen after return is the number of ocetes consumed.
@@ -1853,7 +1861,7 @@
         return(-1);
     }
 
-    /* 
+    /*
      * TODO(jungshik)
      * 1. is ucnv_convert(To|From)Algorithmic better?
      * 2. had we better use an explicit pivot buffer?
@@ -1871,7 +1879,7 @@
                        &ucv_in, ucv_in + *inlen, NULL, NULL, NULL, NULL,
                        0, TRUE, &err);
     }
-    *inlen = ucv_in - (const char*) in; 
+    *inlen = ucv_in - (const char*) in;
     *outlen = ucv_out - (char *) out;
     if (U_SUCCESS(err))
         return 0;
@@ -1889,24 +1897,28 @@
  *		The real API used by libxml for on-the-fly conversion	*
  *									*
  ************************************************************************/
+int
+xmlCharEncFirstLineInt(xmlCharEncodingHandler *handler, xmlBufferPtr out,
+                       xmlBufferPtr in, int len);
 
 /**
- * xmlCharEncFirstLine:
+ * xmlCharEncFirstLineInt:
  * @handler:	char enconding transformation data structure
  * @out:  an xmlBuffer for the output.
  * @in:  an xmlBuffer for the input
- *     
+ * @len:  number of bytes to convert for the first line, or -1
+ *
  * 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 
+ *
+ * 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) {
+xmlCharEncFirstLineInt(xmlCharEncodingHandler *handler, xmlBufferPtr out,
+                       xmlBufferPtr in, int len) {
     int ret = -2;
     int written;
     int toconv;
@@ -1916,16 +1928,23 @@
     if (in == NULL) return(-1);
 
     /* calculate space available */
-    written = out->size - out->use;
+    written = out->size - out->use - 1; /* count '\0' */
     toconv = in->use;
     /*
      * echo '<?xml version="1.0" encoding="UCS4"?>' | wc -c => 38
      * 45 chars should be sufficient to reach the end of the encoding
      * declaration without going too far inside the document content.
      * on UTF-16 this means 90bytes, on UCS4 this means 180
+     * The actual value depending on guessed encoding is passed as @len
+     * if provided
      */
-    if (toconv > 180)
-	toconv  = 180;
+    if (len >= 0) {
+        if (toconv > len)
+            toconv = len;
+    } else {
+        if (toconv > 180)
+            toconv = 180;
+    }
     if (toconv * 2 >= written) {
         xmlBufferGrow(out, toconv);
 	written = out->size - out->use - 1;
@@ -1990,14 +2009,34 @@
 }
 
 /**
+ * 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) {
+    return(xmlCharEncFirstLineInt(handler, out, in, -1));
+}
+
+/**
  * xmlCharEncInFunc:
  * @handler:	char encoding transformation data structure
  * @out:  an xmlBuffer for the output.
  * @in:  an xmlBuffer for the input
- *     
+ *
  * Generic front-end for the encoding handler input function
- *     
- * Returns the number of byte written if success, or 
+ *
+ * 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
@@ -2020,7 +2059,7 @@
     toconv = in->use;
     if (toconv == 0)
         return (0);
-    written = out->size - out->use;
+    written = out->size - out->use -1; /* count '\0' */
     if (toconv * 2 >= written) {
         xmlBufferGrow(out, out->size + toconv * 2);
         written = out->size - out->use - 1;
@@ -2079,7 +2118,7 @@
         case -2: {
             char buf[50];
 
-	    snprintf(&buf[0], 49, "0x%02X 0x%02X 0x%02X 0x%02X", 
+	    snprintf(&buf[0], 49, "0x%02X 0x%02X 0x%02X 0x%02X",
 		     in->content[0], in->content[1],
 		     in->content[2], in->content[3]);
 	    buf[49] = 0;
@@ -2101,15 +2140,15 @@
  * @handler:	char enconding transformation data structure
  * @out:  an xmlBuffer for the output.
  * @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 
+ * 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 
+ *
+ * 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
@@ -2127,7 +2166,7 @@
     if (out == NULL) return(-1);
 
 retry:
-    
+
     written = out->size - out->use;
 
     if (written > 0)
@@ -2290,7 +2329,7 @@
 	    } else {
 		char buf[50];
 
-		snprintf(&buf[0], 49, "0x%02X 0x%02X 0x%02X 0x%02X", 
+		snprintf(&buf[0], 49, "0x%02X 0x%02X 0x%02X 0x%02X",
 			 in->content[0], in->content[1],
 			 in->content[2], in->content[3]);
 		buf[49] = 0;
@@ -2309,7 +2348,7 @@
 /**
  * xmlCharEncCloseFunc:
  * @handler:	char enconding transformation data structure
- *     
+ *
  * Generic front-end for encoding handler close function
  *
  * Returns 0 if success, or -1 in case of error
@@ -2317,6 +2356,7 @@
 int
 xmlCharEncCloseFunc(xmlCharEncodingHandler *handler) {
     int ret = 0;
+    int tofree = 0;
     if (handler == NULL) return(-1);
     if (handler->name == NULL) return(-1);
 #ifdef LIBXML_ICONV_ENABLED
@@ -2325,9 +2365,7 @@
      * and the associated icon resources.
      */
     if ((handler->iconv_out != NULL) || (handler->iconv_in != NULL)) {
-	if (handler->name != NULL)
-	    xmlFree(handler->name);
-	handler->name = NULL;
+        tofree = 1;
 	if (handler->iconv_out != NULL) {
 	    if (iconv_close(handler->iconv_out))
 		ret = -1;
@@ -2338,14 +2376,11 @@
 		ret = -1;
 	    handler->iconv_in = NULL;
 	}
-	xmlFree(handler);
     }
 #endif /* LIBXML_ICONV_ENABLED */
 #ifdef LIBXML_ICU_ENABLED
     if ((handler->uconv_out != NULL) || (handler->uconv_in != NULL)) {
-	if (handler->name != NULL)
-	    xmlFree(handler->name);
-	handler->name = NULL;
+        tofree = 1;
 	if (handler->uconv_out != NULL) {
 	    closeIcuConverter(handler->uconv_out);
 	    handler->uconv_out = NULL;
@@ -2354,9 +2389,15 @@
 	    closeIcuConverter(handler->uconv_in);
 	    handler->uconv_in = NULL;
 	}
-	xmlFree(handler);
     }
 #endif
+    if (tofree) {
+        /* free up only dynamic handlers iconv/uconv */
+        if (handler->name != NULL)
+            xmlFree(handler->name);
+        handler->name = NULL;
+        xmlFree(handler);
+    }
 #ifdef DEBUG_ENCODING
     if (ret)
         xmlGenericError(xmlGenericErrorContext,
@@ -2386,7 +2427,7 @@
 long
 xmlByteConsumed(xmlParserCtxtPtr ctxt) {
     xmlParserInputPtr in;
-    
+
     if (ctxt == NULL) return(-1);
     in = ctxt->input;
     if (in == NULL)  return(-1);
@@ -2448,6 +2489,7 @@
 		    unused += written;
 		    cur += toconv;
 		} while (ret == -2);
+#endif
             } else {
 	        /* could not find a converter */
 	        return(-1);
@@ -2459,7 +2501,6 @@
     }
     return(in->consumed + (in->cur - in->base));
 }
-#endif
 
 #if !defined(LIBXML_ICONV_ENABLED) && !defined(LIBXML_ICU_ENABLED)
 #ifdef LIBXML_ISO8859X_ENABLED
@@ -2487,6 +2528,7 @@
     const unsigned char* outstart = out;
     const unsigned char* inend;
     const unsigned char* instart = in;
+    const unsigned char* processed = in;
 
     if ((out == NULL) || (outlen == NULL) || (inlen == NULL) ||
         (xlattable == NULL))
@@ -2503,81 +2545,82 @@
     while (in < inend) {
         unsigned char d = *in++;
         if  (d < 0x80)  {
-            *out++ = d; 
+            *out++ = d;
         } else if (d < 0xC0) {
             /* trailing byte in leading position */
             *outlen = out - outstart;
-            *inlen = in - instart - 1;
+            *inlen = processed - instart;
             return(-2);
         } else if (d < 0xE0) {
             unsigned char c;
             if (!(in < inend)) {
                 /* trailing byte not in input buffer */
                 *outlen = out - outstart;
-                *inlen = in - instart - 1;
-                return(-2);
+                *inlen = processed - instart;
+                return(-3);
             }
             c = *in++;
             if ((c & 0xC0) != 0x80) {
                 /* not a trailing byte */
                 *outlen = out - outstart;
-                *inlen = in - instart - 2;
+                *inlen = processed - instart;
                 return(-2);
             }
-            c = c & 0x3F; 
+            c = c & 0x3F;
             d = d & 0x1F;
             d = xlattable [48 + c + xlattable [d] * 64];
             if (d == 0) {
                 /* not in character set */
                 *outlen = out - outstart;
-                *inlen = in - instart - 2;
+                *inlen = processed - instart;
                 return(-2);
             }
-            *out++ = d; 
+            *out++ = d;
         } else if (d < 0xF0) {
             unsigned char c1;
             unsigned char c2;
             if (!(in < inend - 1)) {
                 /* trailing bytes not in input buffer */
                 *outlen = out - outstart;
-                *inlen = in - instart - 1;
-                return(-2);
+                *inlen = processed - instart;
+                return(-3);
             }
             c1 = *in++;
             if ((c1 & 0xC0) != 0x80) {
                 /* not a trailing byte (c1) */
                 *outlen = out - outstart;
-                *inlen = in - instart - 2;
+                *inlen = processed - instart;
                 return(-2);
             }
             c2 = *in++;
             if ((c2 & 0xC0) != 0x80) {
                 /* not a trailing byte (c2) */
                 *outlen = out - outstart;
-                *inlen = in - instart - 2;
+                *inlen = processed - instart;
                 return(-2);
             }
-            c1 = c1 & 0x3F; 
-            c2 = c2 & 0x3F; 
+            c1 = c1 & 0x3F;
+            c2 = c2 & 0x3F;
 	    d = d & 0x0F;
-	    d = xlattable [48 + c2 + xlattable [48 + c1 + 
+	    d = xlattable [48 + c2 + xlattable [48 + c1 +
 	    		xlattable [32 + d] * 64] * 64];
             if (d == 0) {
                 /* not in character set */
                 *outlen = out - outstart;
-                *inlen = in - instart - 3;
+                *inlen = processed - instart;
                 return(-2);
             }
-            *out++ = d; 
+            *out++ = d;
         } else {
             /* cannot transcode >= U+010000 */
             *outlen = out - outstart;
-            *inlen = in - instart - 1;
+            *inlen = processed - instart;
             return(-2);
         }
+        processed = in;
     }
     *outlen = out - outstart;
-    *inlen = in - instart;
+    *inlen = processed - instart;
     return(*outlen);
 }
 
@@ -2611,16 +2654,16 @@
     outend = out + *outlen;
     inend = in + *inlen;
     instop = inend;
-    c = *in;
-    while (in < inend && out < outend - 1) {
-        if (c >= 0x80) {
-            c = unicodetable [c - 0x80];
+
+    while ((in < inend) && (out < outend - 2)) {
+        if (*in >= 0x80) {
+            c = unicodetable [*in - 0x80];
             if (c == 0) {
                 /* undefined code point */
                 *outlen = out - outstart;
                 *inlen = in - instart;
                 return (-1);
-            } 
+            }
             if (c < 0x800) {
                 *out++ = ((c >>  6) & 0x1F) | 0xC0;
                 *out++ = (c & 0x3F) | 0x80;
@@ -2628,48 +2671,47 @@
                 *out++ = ((c >>  12) & 0x0F) | 0xE0;
                 *out++ = ((c >>  6) & 0x3F) | 0x80;
                 *out++ = (c & 0x3F) | 0x80;
-            }    
+            }
             ++in;
-            c = *in;
         }
-        if (instop - in > outend - out) instop = in + (outend - out); 
-        while (c < 0x80 && in < instop) {
-            *out++ =  c;
-            ++in;
-            c = *in;
+        if (instop - in > outend - out) instop = in + (outend - out);
+        while ((*in < 0x80) && (in < instop)) {
+            *out++ = *in++;
         }
-    }   
-    if (in < inend && out < outend && c < 0x80) {
-        *out++ =  c;
-        ++in;
+    }
+    if ((in < inend) && (out < outend) && (*in < 0x80)) {
+        *out++ =  *in++;
+    }
+    if ((in < inend) && (out < outend) && (*in < 0x80)) {
+        *out++ =  *in++;
     }
     *outlen = out - outstart;
     *inlen = in - instart;
     return (*outlen);
 }
 
-    
+
 /************************************************************************
  * Lookup tables for ISO-8859-2..ISO-8859-16 transcoding                *
  ************************************************************************/
 
 static unsigned short const xmlunicodetable_ISO8859_2 [128] = {
-    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 
-    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 
-    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 
-    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 
-    0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7, 
-    0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b, 
-    0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7, 
-    0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, 
-    0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, 
-    0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, 
-    0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, 
-    0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, 
-    0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, 
-    0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, 
-    0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, 
-    0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9, 
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+    0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7,
+    0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b,
+    0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7,
+    0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c,
+    0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7,
+    0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e,
+    0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7,
+    0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df,
+    0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7,
+    0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f,
+    0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7,
+    0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9,
 };
 
 static unsigned char const xmltranscodetable_ISO8859_2 [48 + 6 * 64] = {
@@ -2703,22 +2745,22 @@
 };
 
 static unsigned short const xmlunicodetable_ISO8859_3 [128] = {
-    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 
-    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 
-    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 
-    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 
-    0x00a0, 0x0126, 0x02d8, 0x00a3, 0x00a4, 0x0000, 0x0124, 0x00a7, 
-    0x00a8, 0x0130, 0x015e, 0x011e, 0x0134, 0x00ad, 0x0000, 0x017b, 
-    0x00b0, 0x0127, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x0125, 0x00b7, 
-    0x00b8, 0x0131, 0x015f, 0x011f, 0x0135, 0x00bd, 0x0000, 0x017c, 
-    0x00c0, 0x00c1, 0x00c2, 0x0000, 0x00c4, 0x010a, 0x0108, 0x00c7, 
-    0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 
-    0x0000, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x0120, 0x00d6, 0x00d7, 
-    0x011c, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x016c, 0x015c, 0x00df, 
-    0x00e0, 0x00e1, 0x00e2, 0x0000, 0x00e4, 0x010b, 0x0109, 0x00e7, 
-    0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 
-    0x0000, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x0121, 0x00f6, 0x00f7, 
-    0x011d, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x016d, 0x015d, 0x02d9, 
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+    0x00a0, 0x0126, 0x02d8, 0x00a3, 0x00a4, 0x0000, 0x0124, 0x00a7,
+    0x00a8, 0x0130, 0x015e, 0x011e, 0x0134, 0x00ad, 0x0000, 0x017b,
+    0x00b0, 0x0127, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x0125, 0x00b7,
+    0x00b8, 0x0131, 0x015f, 0x011f, 0x0135, 0x00bd, 0x0000, 0x017c,
+    0x00c0, 0x00c1, 0x00c2, 0x0000, 0x00c4, 0x010a, 0x0108, 0x00c7,
+    0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+    0x0000, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x0120, 0x00d6, 0x00d7,
+    0x011c, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x016c, 0x015c, 0x00df,
+    0x00e0, 0x00e1, 0x00e2, 0x0000, 0x00e4, 0x010b, 0x0109, 0x00e7,
+    0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+    0x0000, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x0121, 0x00f6, 0x00f7,
+    0x011d, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x016d, 0x015d, 0x02d9,
 };
 
 static unsigned char const xmltranscodetable_ISO8859_3 [48 + 7 * 64] = {
@@ -2756,22 +2798,22 @@
 };
 
 static unsigned short const xmlunicodetable_ISO8859_4 [128] = {
-    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 
-    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 
-    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 
-    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 
-    0x00a0, 0x0104, 0x0138, 0x0156, 0x00a4, 0x0128, 0x013b, 0x00a7, 
-    0x00a8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00ad, 0x017d, 0x00af, 
-    0x00b0, 0x0105, 0x02db, 0x0157, 0x00b4, 0x0129, 0x013c, 0x02c7, 
-    0x00b8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014a, 0x017e, 0x014b, 
-    0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, 
-    0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x012a, 
-    0x0110, 0x0145, 0x014c, 0x0136, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 
-    0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x0168, 0x016a, 0x00df, 
-    0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, 
-    0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b, 
-    0x0111, 0x0146, 0x014d, 0x0137, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 
-    0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x0169, 0x016b, 0x02d9, 
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+    0x00a0, 0x0104, 0x0138, 0x0156, 0x00a4, 0x0128, 0x013b, 0x00a7,
+    0x00a8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00ad, 0x017d, 0x00af,
+    0x00b0, 0x0105, 0x02db, 0x0157, 0x00b4, 0x0129, 0x013c, 0x02c7,
+    0x00b8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014a, 0x017e, 0x014b,
+    0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e,
+    0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x012a,
+    0x0110, 0x0145, 0x014c, 0x0136, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
+    0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x0168, 0x016a, 0x00df,
+    0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f,
+    0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b,
+    0x0111, 0x0146, 0x014d, 0x0137, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
+    0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x0169, 0x016b, 0x02d9,
 };
 
 static unsigned char const xmltranscodetable_ISO8859_4 [48 + 6 * 64] = {
@@ -2805,22 +2847,22 @@
 };
 
 static unsigned short const xmlunicodetable_ISO8859_5 [128] = {
-    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 
-    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 
-    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 
-    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 
-    0x00a0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 
-    0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x00ad, 0x040e, 0x040f, 
-    0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 
-    0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, 
-    0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 
-    0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 
-    0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 
-    0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 
-    0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 
-    0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, 
-    0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 
-    0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x00a7, 0x045e, 0x045f, 
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+    0x00a0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407,
+    0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x00ad, 0x040e, 0x040f,
+    0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
+    0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
+    0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+    0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f,
+    0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
+    0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f,
+    0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
+    0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f,
+    0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
+    0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x00a7, 0x045e, 0x045f,
 };
 
 static unsigned char const xmltranscodetable_ISO8859_5 [48 + 6 * 64] = {
@@ -2854,22 +2896,22 @@
 };
 
 static unsigned short const xmlunicodetable_ISO8859_6 [128] = {
-    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 
-    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 
-    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 
-    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 
-    0x00a0, 0x0000, 0x0000, 0x0000, 0x00a4, 0x0000, 0x0000, 0x0000, 
-    0x0000, 0x0000, 0x0000, 0x0000, 0x060c, 0x00ad, 0x0000, 0x0000, 
-    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
-    0x0000, 0x0000, 0x0000, 0x061b, 0x0000, 0x0000, 0x0000, 0x061f, 
-    0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 
-    0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, 
-    0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 
-    0x0638, 0x0639, 0x063a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
-    0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 
-    0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, 
-    0x0650, 0x0651, 0x0652, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
-    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+    0x00a0, 0x0000, 0x0000, 0x0000, 0x00a4, 0x0000, 0x0000, 0x0000,
+    0x0000, 0x0000, 0x0000, 0x0000, 0x060c, 0x00ad, 0x0000, 0x0000,
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    0x0000, 0x0000, 0x0000, 0x061b, 0x0000, 0x0000, 0x0000, 0x061f,
+    0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
+    0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f,
+    0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637,
+    0x0638, 0x0639, 0x063a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647,
+    0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f,
+    0x0650, 0x0651, 0x0652, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 };
 
 static unsigned char const xmltranscodetable_ISO8859_6 [48 + 5 * 64] = {
@@ -2899,22 +2941,22 @@
 };
 
 static unsigned short const xmlunicodetable_ISO8859_7 [128] = {
-    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 
-    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 
-    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 
-    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 
-    0x00a0, 0x2018, 0x2019, 0x00a3, 0x0000, 0x0000, 0x00a6, 0x00a7, 
-    0x00a8, 0x00a9, 0x0000, 0x00ab, 0x00ac, 0x00ad, 0x0000, 0x2015, 
-    0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x0385, 0x0386, 0x00b7, 
-    0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f, 
-    0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 
-    0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 
-    0x03a0, 0x03a1, 0x0000, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 
-    0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, 
-    0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 
-    0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 
-    0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 
-    0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x0000, 
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+    0x00a0, 0x2018, 0x2019, 0x00a3, 0x0000, 0x0000, 0x00a6, 0x00a7,
+    0x00a8, 0x00a9, 0x0000, 0x00ab, 0x00ac, 0x00ad, 0x0000, 0x2015,
+    0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x0385, 0x0386, 0x00b7,
+    0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f,
+    0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+    0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f,
+    0x03a0, 0x03a1, 0x0000, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7,
+    0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af,
+    0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
+    0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
+    0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7,
+    0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x0000,
 };
 
 static unsigned char const xmltranscodetable_ISO8859_7 [48 + 7 * 64] = {
@@ -2952,22 +2994,22 @@
 };
 
 static unsigned short const xmlunicodetable_ISO8859_8 [128] = {
-    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 
-    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 
-    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 
-    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 
-    0x00a0, 0x0000, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 
-    0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, 
-    0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 
-    0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x0000, 
-    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
-    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
-    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
-    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2017, 
-    0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, 
-    0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, 
-    0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, 
-    0x05e8, 0x05e9, 0x05ea, 0x0000, 0x0000, 0x200e, 0x200f, 0x0000, 
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+    0x00a0, 0x0000, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
+    0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
+    0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
+    0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x0000,
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2017,
+    0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7,
+    0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df,
+    0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7,
+    0x05e8, 0x05e9, 0x05ea, 0x0000, 0x0000, 0x200e, 0x200f, 0x0000,
 };
 
 static unsigned char const xmltranscodetable_ISO8859_8 [48 + 7 * 64] = {
@@ -3005,22 +3047,22 @@
 };
 
 static unsigned short const xmlunicodetable_ISO8859_9 [128] = {
-    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 
-    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 
-    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 
-    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 
-    0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 
-    0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, 
-    0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 
-    0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, 
-    0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 
-    0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 
-    0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 
-    0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df, 
-    0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 
-    0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 
-    0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 
-    0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff, 
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+    0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
+    0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
+    0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
+    0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
+    0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
+    0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+    0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
+    0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df,
+    0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
+    0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+    0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
+    0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff,
 };
 
 static unsigned char const xmltranscodetable_ISO8859_9 [48 + 5 * 64] = {
@@ -3050,22 +3092,22 @@
 };
 
 static unsigned short const xmlunicodetable_ISO8859_10 [128] = {
-    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 
-    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 
-    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 
-    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 
-    0x00a0, 0x0104, 0x0112, 0x0122, 0x012a, 0x0128, 0x0136, 0x00a7, 
-    0x013b, 0x0110, 0x0160, 0x0166, 0x017d, 0x00ad, 0x016a, 0x014a, 
-    0x00b0, 0x0105, 0x0113, 0x0123, 0x012b, 0x0129, 0x0137, 0x00b7, 
-    0x013c, 0x0111, 0x0161, 0x0167, 0x017e, 0x2015, 0x016b, 0x014b, 
-    0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, 
-    0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x00cf, 
-    0x00d0, 0x0145, 0x014c, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0168, 
-    0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, 
-    0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, 
-    0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x00ef, 
-    0x00f0, 0x0146, 0x014d, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0169, 
-    0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x0138, 
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+    0x00a0, 0x0104, 0x0112, 0x0122, 0x012a, 0x0128, 0x0136, 0x00a7,
+    0x013b, 0x0110, 0x0160, 0x0166, 0x017d, 0x00ad, 0x016a, 0x014a,
+    0x00b0, 0x0105, 0x0113, 0x0123, 0x012b, 0x0129, 0x0137, 0x00b7,
+    0x013c, 0x0111, 0x0161, 0x0167, 0x017e, 0x2015, 0x016b, 0x014b,
+    0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e,
+    0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x00cf,
+    0x00d0, 0x0145, 0x014c, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0168,
+    0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
+    0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f,
+    0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x00ef,
+    0x00f0, 0x0146, 0x014d, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0169,
+    0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x0138,
 };
 
 static unsigned char const xmltranscodetable_ISO8859_10 [48 + 7 * 64] = {
@@ -3103,22 +3145,22 @@
 };
 
 static unsigned short const xmlunicodetable_ISO8859_11 [128] = {
-    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 
-    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 
-    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 
-    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 
-    0x00a0, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, 
-    0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, 
-    0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, 
-    0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, 
-    0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, 
-    0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, 
-    0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, 
-    0x0e38, 0x0e39, 0x0e3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0e3f, 
-    0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, 
-    0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f, 
-    0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, 
-    0x0e58, 0x0e59, 0x0e5a, 0x0e5b, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+    0x00a0, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07,
+    0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f,
+    0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17,
+    0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f,
+    0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27,
+    0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f,
+    0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37,
+    0x0e38, 0x0e39, 0x0e3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0e3f,
+    0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47,
+    0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f,
+    0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57,
+    0x0e58, 0x0e59, 0x0e5a, 0x0e5b, 0x0000, 0x0000, 0x0000, 0x0000,
 };
 
 static unsigned char const xmltranscodetable_ISO8859_11 [48 + 6 * 64] = {
@@ -3152,22 +3194,22 @@
 };
 
 static unsigned short const xmlunicodetable_ISO8859_13 [128] = {
-    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 
-    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 
-    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 
-    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 
-    0x00a0, 0x201d, 0x00a2, 0x00a3, 0x00a4, 0x201e, 0x00a6, 0x00a7, 
-    0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6, 
-    0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x201c, 0x00b5, 0x00b6, 0x00b7, 
-    0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6, 
-    0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112, 
-    0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b, 
-    0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, 
-    0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df, 
-    0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113, 
-    0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c, 
-    0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, 
-    0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, 0x2019, 
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+    0x00a0, 0x201d, 0x00a2, 0x00a3, 0x00a4, 0x201e, 0x00a6, 0x00a7,
+    0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6,
+    0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x201c, 0x00b5, 0x00b6, 0x00b7,
+    0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6,
+    0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112,
+    0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b,
+    0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7,
+    0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df,
+    0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113,
+    0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c,
+    0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7,
+    0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, 0x2019,
 };
 
 static unsigned char const xmltranscodetable_ISO8859_13 [48 + 7 * 64] = {
@@ -3205,22 +3247,22 @@
 };
 
 static unsigned short const xmlunicodetable_ISO8859_14 [128] = {
-    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 
-    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 
-    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 
-    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 
-    0x00a0, 0x1e02, 0x1e03, 0x00a3, 0x010a, 0x010b, 0x1e0a, 0x00a7, 
-    0x1e80, 0x00a9, 0x1e82, 0x1e0b, 0x1ef2, 0x00ad, 0x00ae, 0x0178, 
-    0x1e1e, 0x1e1f, 0x0120, 0x0121, 0x1e40, 0x1e41, 0x00b6, 0x1e56, 
-    0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61, 
-    0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 
-    0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 
-    0x0174, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x1e6a, 
-    0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x0176, 0x00df, 
-    0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 
-    0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 
-    0x0175, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x1e6b, 
-    0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x0177, 0x00ff, 
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+    0x00a0, 0x1e02, 0x1e03, 0x00a3, 0x010a, 0x010b, 0x1e0a, 0x00a7,
+    0x1e80, 0x00a9, 0x1e82, 0x1e0b, 0x1ef2, 0x00ad, 0x00ae, 0x0178,
+    0x1e1e, 0x1e1f, 0x0120, 0x0121, 0x1e40, 0x1e41, 0x00b6, 0x1e56,
+    0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61,
+    0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
+    0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+    0x0174, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x1e6a,
+    0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x0176, 0x00df,
+    0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
+    0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+    0x0175, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x1e6b,
+    0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x0177, 0x00ff,
 };
 
 static unsigned char const xmltranscodetable_ISO8859_14 [48 + 10 * 64] = {
@@ -3270,22 +3312,22 @@
 };
 
 static unsigned short const xmlunicodetable_ISO8859_15 [128] = {
-    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 
-    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 
-    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 
-    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 
-    0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0160, 0x00a7, 
-    0x0161, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, 
-    0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x017d, 0x00b5, 0x00b6, 0x00b7, 
-    0x017e, 0x00b9, 0x00ba, 0x00bb, 0x0152, 0x0153, 0x0178, 0x00bf, 
-    0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 
-    0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 
-    0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 
-    0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, 
-    0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 
-    0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 
-    0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 
-    0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff, 
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+    0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0160, 0x00a7,
+    0x0161, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
+    0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x017d, 0x00b5, 0x00b6, 0x00b7,
+    0x017e, 0x00b9, 0x00ba, 0x00bb, 0x0152, 0x0153, 0x0178, 0x00bf,
+    0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
+    0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+    0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
+    0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
+    0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
+    0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+    0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
+    0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff,
 };
 
 static unsigned char const xmltranscodetable_ISO8859_15 [48 + 6 * 64] = {
@@ -3319,22 +3361,22 @@
 };
 
 static unsigned short const xmlunicodetable_ISO8859_16 [128] = {
-    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 
-    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 
-    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 
-    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 
-    0x00a0, 0x0104, 0x0105, 0x0141, 0x20ac, 0x201e, 0x0160, 0x00a7, 
-    0x0161, 0x00a9, 0x0218, 0x00ab, 0x0179, 0x00ad, 0x017a, 0x017b, 
-    0x00b0, 0x00b1, 0x010c, 0x0142, 0x017d, 0x201d, 0x00b6, 0x00b7, 
-    0x017e, 0x010d, 0x0219, 0x00bb, 0x0152, 0x0153, 0x0178, 0x017c, 
-    0x00c0, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0106, 0x00c6, 0x00c7, 
-    0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 
-    0x0110, 0x0143, 0x00d2, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x015a, 
-    0x0170, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0118, 0x021a, 0x00df, 
-    0x00e0, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x0107, 0x00e6, 0x00e7, 
-    0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 
-    0x0111, 0x0144, 0x00f2, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x015b, 
-    0x0171, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0119, 0x021b, 0x00ff, 
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+    0x00a0, 0x0104, 0x0105, 0x0141, 0x20ac, 0x201e, 0x0160, 0x00a7,
+    0x0161, 0x00a9, 0x0218, 0x00ab, 0x0179, 0x00ad, 0x017a, 0x017b,
+    0x00b0, 0x00b1, 0x010c, 0x0142, 0x017d, 0x201d, 0x00b6, 0x00b7,
+    0x017e, 0x010d, 0x0219, 0x00bb, 0x0152, 0x0153, 0x0178, 0x017c,
+    0x00c0, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0106, 0x00c6, 0x00c7,
+    0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+    0x0110, 0x0143, 0x00d2, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x015a,
+    0x0170, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0118, 0x021a, 0x00df,
+    0x00e0, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x0107, 0x00e6, 0x00e7,
+    0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+    0x0111, 0x0144, 0x00f2, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x015b,
+    0x0171, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0119, 0x021b, 0x00ff,
 };
 
 static unsigned char const xmltranscodetable_ISO8859_16 [48 + 9 * 64] = {
diff --git a/entities.c b/entities.c
index c171e97..6aef49f 100644
--- a/entities.c
+++ b/entities.c
@@ -690,7 +690,7 @@
 	}
 	cur++;
     }
-    *out++ = 0;
+    *out = 0;
     return(buffer);
 }
 
@@ -772,7 +772,7 @@
 	}
 	cur++;
     }
-    *out++ = 0;
+    *out = 0;
     return(buffer);
 }
 
diff --git a/error.c b/error.c
index 5f03d94..a891faa 100644
--- a/error.c
+++ b/error.c
@@ -132,7 +132,7 @@
  */
 void
 xmlSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler) {
-    xmlGenericErrorContext = ctx;
+    xmlStructuredErrorContext = ctx;
     xmlStructuredError = handler;
 }
 
@@ -452,6 +452,8 @@
     xmlErrorPtr to = &xmlLastError;
     xmlNodePtr baseptr = NULL;
 
+    if (code == XML_ERR_OK)
+        return;
     if ((xmlGetWarningsDefaultValue == 0) && (level == XML_ERR_WARNING))
         return;
     if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
@@ -459,8 +461,11 @@
 	(domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
 	ctxt = (xmlParserCtxtPtr) ctx;
 	if ((schannel == NULL) && (ctxt != NULL) && (ctxt->sax != NULL) &&
-	    (ctxt->sax->initialized == XML_SAX2_MAGIC))
+	    (ctxt->sax->initialized == XML_SAX2_MAGIC) &&
+	    (ctxt->sax->serror != NULL)) {
 	    schannel = ctxt->sax->serror;
+	    data = ctxt->userData;
+	}
     }
     /*
      * Check if structured error handler set
@@ -471,18 +476,8 @@
 	 * if user has defined handler, change data ptr to user's choice
 	 */
 	if (schannel != NULL)
-	    data = xmlGenericErrorContext;
+	    data = xmlStructuredErrorContext;
     }
-    if ((domain == XML_FROM_VALID) &&
-        ((channel == xmlParserValidityError) ||
-	 (channel == xmlParserValidityWarning))) {
-	ctxt = (xmlParserCtxtPtr) ctx;
-	if ((schannel == NULL) && (ctxt != NULL) && (ctxt->sax != NULL) &&
-	    (ctxt->sax->initialized == XML_SAX2_MAGIC))
-	    schannel = ctxt->sax->serror;
-    }
-    if (code == XML_ERR_OK)
-        return;
     /*
      * Formatting the message
      */
@@ -573,7 +568,6 @@
 	if ((to->file == NULL) && (node != NULL) && (node->doc != NULL)) {
 	    to->file = (char *) xmlStrdup(node->doc->URL);
 	}
-	file = to->file;
     }
     to->line = line;
     if (str1 != NULL)
@@ -590,27 +584,25 @@
     if (to != &xmlLastError)
         xmlCopyError(to,&xmlLastError);
 
+    if (schannel != NULL) {
+	schannel(data, to);
+	return;
+    }
+
     /*
      * Find the callback channel if channel param is NULL
      */
-    if ((ctxt != NULL) && (channel == NULL) && (xmlStructuredError == NULL) && (ctxt->sax != NULL)) {
+    if ((ctxt != NULL) && (channel == NULL) &&
+        (xmlStructuredError == NULL) && (ctxt->sax != NULL)) {
         if (level == XML_ERR_WARNING)
 	    channel = ctxt->sax->warning;
         else
 	    channel = ctxt->sax->error;
 	data = ctxt->userData;
     } else if (channel == NULL) {
-        if (xmlStructuredError != NULL)
-	    schannel = xmlStructuredError;
-	else
-	    channel = xmlGenericError;
-	if (!data) {
-	data = xmlGenericErrorContext;
-    }
-    }
-    if (schannel != NULL) {
-        schannel(data, to);
-	return;
+	channel = xmlGenericError;
+	if (!data)
+	    data = xmlGenericErrorContext;
     }
     if (channel == NULL)
         return;
@@ -927,6 +919,7 @@
 
     if (ctxt == NULL)
         return;
+    ctxt->errNo = XML_ERR_OK;
     if (ctxt->lastError.code == XML_ERR_OK)
         return;
     xmlResetError(&ctxt->lastError);
diff --git a/globals.c b/globals.c
index cbc6625..69002f0 100644
--- a/globals.c
+++ b/globals.c
@@ -46,7 +46,8 @@
  */
 void xmlInitGlobals(void)
 {
-    xmlThrDefMutex = xmlNewMutex();
+    if (xmlThrDefMutex == NULL)
+        xmlThrDefMutex = xmlNewMutex();
 }
 
 /**
@@ -148,6 +149,7 @@
 #undef	xmlGenericError
 #undef	xmlStructuredError
 #undef	xmlGenericErrorContext
+#undef	xmlStructuredErrorContext
 #undef	xmlGetWarningsDefaultValue
 #undef	xmlIndentTreeOutput
 #undef  xmlTreeIndentString
@@ -314,6 +316,13 @@
  */
 void *xmlGenericErrorContext = NULL;
 static void *xmlGenericErrorContextThrDef = NULL;
+/**
+ * xmlStructuredErrorContext:
+ *
+ * Global setting passed to structured error callbacks
+ */
+void *xmlStructuredErrorContext = NULL;
+static void *xmlStructuredErrorContextThrDef = NULL;
 xmlError xmlLastError;
 
 /*
@@ -545,6 +554,7 @@
     gs->xmlGenericError = xmlGenericErrorThrDef;
     gs->xmlStructuredError = xmlStructuredErrorThrDef;
     gs->xmlGenericErrorContext = xmlGenericErrorContextThrDef;
+    gs->xmlStructuredErrorContext = xmlStructuredErrorContextThrDef;
     gs->xmlRegisterNodeDefaultValue = xmlRegisterNodeDefaultValueThrDef;
     gs->xmlDeregisterNodeDefaultValue = xmlDeregisterNodeDefaultValueThrDef;
 
@@ -573,7 +583,7 @@
 void
 xmlThrDefSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler) {
     xmlMutexLock(xmlThrDefMutex);
-    xmlGenericErrorContextThrDef = ctx;
+    xmlStructuredErrorContextThrDef = ctx;
     xmlStructuredErrorThrDef = handler;
     xmlMutexUnlock(xmlThrDefMutex);
 }
@@ -876,6 +886,15 @@
 	return (&xmlGetGlobalState()->xmlGenericErrorContext);
 }
 
+#undef	xmlStructuredErrorContext
+void * *
+__xmlStructuredErrorContext(void) {
+    if (IS_MAIN_THREAD)
+	return (&xmlStructuredErrorContext);
+    else
+	return (&xmlGetGlobalState()->xmlStructuredErrorContext);
+}
+
 #undef	xmlGetWarningsDefaultValue
 int *
 __xmlGetWarningsDefaultValue(void) {
@@ -910,7 +929,7 @@
     return ret;
 }
 
-#undef xmlTreeIndentString
+#undef	xmlTreeIndentString
 const char * *
 __xmlTreeIndentString(void) {
     if (IS_MAIN_THREAD)
diff --git a/hash.c b/hash.c
index 22f9bb4..fe1424f 100644
--- a/hash.c
+++ b/hash.c
@@ -3,7 +3,7 @@
  *
  * Reference: Your favorite introductory book on algorithms
  *
- * Copyright (C) 2000 Bjorn Reese and Daniel Veillard.
+ * Copyright (C) 2000,2012 Bjorn Reese and Daniel Veillard.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -21,6 +21,22 @@
 #include "libxml.h"
 
 #include <string.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+/*
+ * Following http://www.ocert.org/advisories/ocert-2011-003.html
+ * it seems that having hash randomization might be a good idea
+ * when using XML with untrusted data
+ */
+#if defined(HAVE_RAND) && defined(HAVE_SRAND) && defined(HAVE_TIME)
+#define HASH_RANDOMIZATION
+#endif
+
 #include <libxml/parser.h>
 #include <libxml/hash.h>
 #include <libxml/xmlmemory.h>
@@ -31,6 +47,10 @@
 
 /* #define DEBUG_GROW */
 
+#ifdef HASH_RANDOMIZATION
+static int hash_initialized = 0;
+#endif
+
 /*
  * A single entry in the hash table
  */
@@ -53,6 +73,9 @@
     int size;
     int nbElems;
     xmlDictPtr dict;
+#ifdef HASH_RANDOMIZATION
+    int random_seed;
+#endif
 };
 
 /*
@@ -65,6 +88,9 @@
     unsigned long value = 0L;
     char ch;
     
+#ifdef HASH_RANDOMIZATION
+    value = table->random_seed;
+#endif
     if (name != NULL) {
 	value += 30 * (*name);
 	while ((ch = *name++) != 0) {
@@ -92,6 +118,9 @@
     unsigned long value = 0L;
     char ch;
     
+#ifdef HASH_RANDOMIZATION
+    value = table->random_seed;
+#endif
     if (prefix != NULL)
 	value += 30 * (*prefix);
     else
@@ -156,6 +185,13 @@
         table->table = xmlMalloc(size * sizeof(xmlHashEntry));
         if (table->table) {
   	    memset(table->table, 0, size * sizeof(xmlHashEntry));
+#ifdef HASH_RANDOMIZATION
+            if (!hash_initialized) {
+                srand(time(NULL));
+                hash_initialized = 1;
+            }
+            table->random_seed = rand();
+#endif
   	    return(table);
         }
         xmlFree(table);
@@ -320,7 +356,6 @@
 		inside_table = 0;
 		iter = next;
 	    }
-	    inside_table = 0;
 	}
 	xmlFree(table->table);
     }
diff --git a/include/libxml/HTMLparser.h b/include/libxml/HTMLparser.h
index 05905e4..10a3d65 100644
--- a/include/libxml/HTMLparser.h
+++ b/include/libxml/HTMLparser.h
@@ -177,12 +177,15 @@
  */
 typedef enum {
     HTML_PARSE_RECOVER  = 1<<0, /* Relaxed parsing */
+    HTML_PARSE_NODEFDTD = 1<<2, /* do not default a doctype if not found */
     HTML_PARSE_NOERROR	= 1<<5,	/* suppress error reports */
     HTML_PARSE_NOWARNING= 1<<6,	/* suppress warning reports */
     HTML_PARSE_PEDANTIC	= 1<<7,	/* pedantic error reporting */
     HTML_PARSE_NOBLANKS	= 1<<8,	/* remove blank nodes */
     HTML_PARSE_NONET	= 1<<11,/* Forbid network access */
-    HTML_PARSE_COMPACT  = 1<<16 /* compact small text nodes */
+    HTML_PARSE_NOIMPLIED= 1<<13,/* Do not add implied html/body... elements */
+    HTML_PARSE_COMPACT  = 1<<16,/* compact small text nodes */
+    HTML_PARSE_IGNORE_ENC=1<<21 /* ignore internal document encoding hint */
 } htmlParserOption;
 
 XMLPUBFUN void XMLCALL
diff --git a/include/libxml/c14n.h b/include/libxml/c14n.h
index a8aa737..3011af7 100644
--- a/include/libxml/c14n.h
+++ b/include/libxml/c14n.h
@@ -52,11 +52,22 @@
  *    ...
  */
 
+/*
+ * xmlC14NMode:
+ * 
+ * Predefined values for C14N modes
+ *
+ */
+typedef enum {
+    XML_C14N_1_0            = 0,    /* Origianal C14N 1.0 spec */
+    XML_C14N_EXCLUSIVE_1_0  = 1,    /* Exclusive C14N 1.0 spec */
+    XML_C14N_1_1            = 2     /* C14N 1.1 spec */
+} xmlC14NMode;
 
 XMLPUBFUN int XMLCALL
 		xmlC14NDocSaveTo	(xmlDocPtr doc,
 					 xmlNodeSetPtr nodes,
-					 int exclusive,
+					 int mode, /* a xmlC14NMode */
 					 xmlChar **inclusive_ns_prefixes,
 					 int with_comments,
 					 xmlOutputBufferPtr buf);
@@ -64,7 +75,7 @@
 XMLPUBFUN int XMLCALL
 		xmlC14NDocDumpMemory	(xmlDocPtr doc,
 					 xmlNodeSetPtr nodes,
-					 int exclusive,
+					 int mode, /* a xmlC14NMode */
 					 xmlChar **inclusive_ns_prefixes,
 					 int with_comments,
 					 xmlChar **doc_txt_ptr);
@@ -72,7 +83,7 @@
 XMLPUBFUN int XMLCALL
 		xmlC14NDocSave		(xmlDocPtr doc,
 					 xmlNodeSetPtr nodes,
-					 int exclusive,
+					 int mode, /* a xmlC14NMode */
 					 xmlChar **inclusive_ns_prefixes,
 					 int with_comments,
 					 const char* filename,
@@ -100,7 +111,7 @@
 		xmlC14NExecute		(xmlDocPtr doc,
 					 xmlC14NIsVisibleCallback is_visible_callback,
 					 void* user_data,
-					 int exclusive,
+					 int mode, /* a xmlC14NMode */
 					 xmlChar **inclusive_ns_prefixes,
 					 int with_comments,
 					 xmlOutputBufferPtr buf);
diff --git a/include/libxml/encoding.h b/include/libxml/encoding.h
index c68ec10..3a3b9b2 100644
--- a/include/libxml/encoding.h
+++ b/include/libxml/encoding.h
@@ -26,24 +26,9 @@
 
 #ifdef LIBXML_ICONV_ENABLED
 #include <iconv.h>
-#else
+#endif
 #ifdef LIBXML_ICU_ENABLED
 #include <unicode/ucnv.h>
-#if 0
-/* Forward-declare UConverter here rather than pulling in <unicode/ucnv.h>
- * to prevent unwanted ICU symbols being exposed to users of libxml2.
- * One particular case is Qt4 conflicting on UChar32.
- */
-#include <stdint.h>
-struct UConverter;
-typedef struct UConverter UConverter;
-#ifdef _MSC_VER
-typedef wchar_t UChar;
-#else
-typedef uint16_t UChar;
-#endif
-#endif
-#endif
 #endif
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/libxml/globals.h b/include/libxml/globals.h
index 57e25fa..9d688e0 100644
--- a/include/libxml/globals.h
+++ b/include/libxml/globals.h
@@ -76,6 +76,7 @@
 #undef	xmlGenericError
 #undef	xmlStructuredError
 #undef	xmlGenericErrorContext
+#undef	xmlStructuredErrorContext
 #undef	xmlGetWarningsDefaultValue
 #undef	xmlIndentTreeOutput
 #undef  xmlTreeIndentString
@@ -158,6 +159,8 @@
 
 	xmlParserInputBufferCreateFilenameFunc xmlParserInputBufferCreateFilenameValue;
 	xmlOutputBufferCreateFilenameFunc xmlOutputBufferCreateFilenameValue;
+
+	void *xmlStructuredErrorContext;
 };
 
 #ifdef __cplusplus
@@ -354,6 +357,14 @@
 XMLPUBVAR void * xmlGenericErrorContext;
 #endif
 
+XMLPUBFUN void * * XMLCALL __xmlStructuredErrorContext(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlStructuredErrorContext \
+(*(__xmlStructuredErrorContext()))
+#else
+XMLPUBVAR void * xmlStructuredErrorContext;
+#endif
+
 XMLPUBFUN int * XMLCALL __xmlGetWarningsDefaultValue(void);
 #ifdef LIBXML_THREAD_ENABLED
 #define xmlGetWarningsDefaultValue \
diff --git a/include/libxml/nanoftp.h b/include/libxml/nanoftp.h
index e3c28a0..397bbba 100644
--- a/include/libxml/nanoftp.h
+++ b/include/libxml/nanoftp.h
@@ -7,7 +7,7 @@
  *
  * Author: Daniel Veillard
  */
- 
+
 #ifndef __NANO_FTP_H__
 #define __NANO_FTP_H__
 
@@ -15,12 +15,31 @@
 
 #ifdef LIBXML_FTP_ENABLED
 
+/* Needed for portability to Windows 64 bits */
+#if defined(__MINGW32__) || defined(_WIN32_WCE)
+#include <winsock2.h>
+#else
+/**
+ * SOCKET:
+ *
+ * macro used to provide portability of code to windows sockets
+ */
+#define SOCKET int
+/**
+ * INVALID_SOCKET:
+ *
+ * macro used to provide portability of code to windows sockets
+ * the value to be used when the socket is not valid
+ */
+#define INVALID_SOCKET (-1)
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /**
- * ftpListCallback: 
+ * ftpListCallback:
  * @userData:  user provided data for the callback
  * @filename:  the file name (including "->" when links are shown)
  * @attrib:  the attribute string
@@ -44,7 +63,7 @@
 				 const char *month, int day, int hour,
 				 int minute);
 /**
- * ftpDataCallback: 
+ * ftpDataCallback:
  * @userData: the user provided context
  * @data: the data received
  * @len: its size in bytes
@@ -60,78 +79,78 @@
  */
 XMLPUBFUN void XMLCALL
 	xmlNanoFTPInit		(void);
-XMLPUBFUN void XMLCALL	
+XMLPUBFUN void XMLCALL
 	xmlNanoFTPCleanup	(void);
 
 /*
  * Creating/freeing contexts.
  */
-XMLPUBFUN void * XMLCALL	
+XMLPUBFUN void * XMLCALL
 	xmlNanoFTPNewCtxt	(const char *URL);
-XMLPUBFUN void XMLCALL	
+XMLPUBFUN void XMLCALL
 	xmlNanoFTPFreeCtxt	(void * ctx);
-XMLPUBFUN void * XMLCALL 	
+XMLPUBFUN void * XMLCALL
 	xmlNanoFTPConnectTo	(const char *server,
 				 int port);
 /*
  * Opening/closing session connections.
  */
-XMLPUBFUN void * XMLCALL 	
+XMLPUBFUN void * XMLCALL
 	xmlNanoFTPOpen		(const char *URL);
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN int XMLCALL
 	xmlNanoFTPConnect	(void *ctx);
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN int XMLCALL
 	xmlNanoFTPClose		(void *ctx);
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN int XMLCALL
 	xmlNanoFTPQuit		(void *ctx);
-XMLPUBFUN void XMLCALL	
+XMLPUBFUN void XMLCALL
 	xmlNanoFTPScanProxy	(const char *URL);
-XMLPUBFUN void XMLCALL	
+XMLPUBFUN void XMLCALL
 	xmlNanoFTPProxy		(const char *host,
 				 int port,
 				 const char *user,
 				 const char *passwd,
 				 int type);
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN int XMLCALL
 	xmlNanoFTPUpdateURL	(void *ctx,
 				 const char *URL);
 
 /*
  * Rather internal commands.
  */
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN int XMLCALL
 	xmlNanoFTPGetResponse	(void *ctx);
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN int XMLCALL
 	xmlNanoFTPCheckResponse	(void *ctx);
 
 /*
  * CD/DIR/GET handlers.
  */
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN int XMLCALL
 	xmlNanoFTPCwd		(void *ctx,
 				 const char *directory);
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN int XMLCALL
 	xmlNanoFTPDele		(void *ctx,
 				 const char *file);
 
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN SOCKET XMLCALL
 	xmlNanoFTPGetConnection	(void *ctx);
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN int XMLCALL
 	xmlNanoFTPCloseConnection(void *ctx);
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN int XMLCALL
 	xmlNanoFTPList		(void *ctx,
 				 ftpListCallback callback,
 				 void *userData,
 				 const char *filename);
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN SOCKET XMLCALL
 	xmlNanoFTPGetSocket	(void *ctx,
 				 const char *filename);
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN int XMLCALL
 	xmlNanoFTPGet		(void *ctx,
 				 ftpDataCallback callback,
 				 void *userData,
 				 const char *filename);
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN int XMLCALL
 	xmlNanoFTPRead		(void *ctx,
 				 void *dest,
 				 int len);
diff --git a/include/libxml/parser.h b/include/libxml/parser.h
index bd9de24..54f1660 100644
--- a/include/libxml/parser.h
+++ b/include/libxml/parser.h
@@ -190,7 +190,10 @@
     const xmlChar    *version;        /* the XML version string */
     const xmlChar   *encoding;        /* the declared encoding, if any */
     int            standalone;        /* standalone document */
-    int                  html;        /* an HTML(1)/Docbook(2) document */
+    int                  html;        /* an HTML(1)/Docbook(2) document
+                                       * 3 is HTML after <head>
+                                       * 10 is HTML after <body>
+                                       */
 
     /* Input stream stack */
     xmlParserInputPtr  input;         /* Current input stream */
@@ -276,7 +279,6 @@
     int                nsNr;          /* the number of inherited namespaces */
     int                nsMax;         /* the size of the arrays */
     const xmlChar *   *nsTab;         /* the array of prefix/namespace name */
-    struct _xmlParserCtxt *nsParent;  /* parent context to inherit namespaces from * */
     int               *attallocs;     /* which attribute were allocated */
     void *            *pushTab;       /* array of data for push */
     xmlHashTablePtr    attsDefault;   /* defaulted attributes if any */
@@ -300,6 +302,12 @@
     xmlParserMode     parseMode;    /* the parser mode */
     unsigned long    nbentities;    /* number of entities references */
     unsigned long  sizeentities;    /* size of parsed entities */
+
+    /* for use by HTML non-recursive parser */
+    xmlParserNodeInfo *nodeInfo;      /* Current NodeInfo */
+    int                nodeInfoNr;    /* Depth of the parsing stack */
+    int                nodeInfoMax;   /* Max depth of the parsing stack */
+    xmlParserNodeInfo *nodeInfoTab;   /* array of nodeInfos */
 };
 
 /**
@@ -595,7 +603,7 @@
  * Display and format a warning messages, callback.
  */
 typedef void (XMLCDECL *warningSAXFunc) (void *ctx,
-				const char *msg, ...) ATTRIBUTE_PRINTF(2,3);
+				const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
 /**
  * errorSAXFunc:
  * @ctx:  an XML parser context
@@ -605,7 +613,7 @@
  * Display and format an error messages, callback.
  */
 typedef void (XMLCDECL *errorSAXFunc) (void *ctx,
-				const char *msg, ...) ATTRIBUTE_PRINTF(2,3);
+				const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
 /**
  * fatalErrorSAXFunc:
  * @ctx:  an XML parser context
@@ -617,7 +625,7 @@
  *       get all the callbacks for errors.
  */
 typedef void (XMLCDECL *fatalErrorSAXFunc) (void *ctx,
-				const char *msg, ...) ATTRIBUTE_PRINTF(2,3);
+				const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
 /**
  * isStandaloneSAXFunc:
  * @ctx:  the user data (XML parser context)
@@ -851,7 +859,7 @@
  * Recovery mode 
  */
 XMLPUBFUN xmlDocPtr XMLCALL	
-		xmlRecoverDoc		(xmlChar *cur);
+		xmlRecoverDoc		(const xmlChar *cur);
 XMLPUBFUN xmlDocPtr XMLCALL	
 		xmlRecoverMemory	(const char *buffer,
 					 int size);
@@ -1097,8 +1105,9 @@
 				   crash if you try to modify the tree) */
     XML_PARSE_OLD10	= 1<<17,/* parse using XML-1.0 before update 5 */
     XML_PARSE_NOBASEFIX = 1<<18,/* do not fixup XINCLUDE xml:base uris */
-    XML_PARSE_HUGE      = 1<<19, /* relax any hardcoded limit from the parser */
-    XML_PARSE_OLDSAX    = 1<<20 /* parse using SAX2 interface from before 2.7.0 */
+    XML_PARSE_HUGE      = 1<<19,/* relax any hardcoded limit from the parser */
+    XML_PARSE_OLDSAX    = 1<<20,/* parse using SAX2 interface before 2.7.0 */
+    XML_PARSE_IGNORE_ENC= 1<<21 /* ignore internal document encoding hint */
 } xmlParserOption;
 
 XMLPUBFUN void XMLCALL
@@ -1215,6 +1224,7 @@
     XML_WITH_DEBUG_RUN = 30,
     XML_WITH_ZLIB = 31,
     XML_WITH_ICU = 32,
+    XML_WITH_LZMA = 33,
     XML_WITH_NONE = 99999 /* just to be sure of allocation size */
 } xmlFeature;
 
diff --git a/include/libxml/relaxng.h b/include/libxml/relaxng.h
index d3e39e0..bdb0a7d 100644
--- a/include/libxml/relaxng.h
+++ b/include/libxml/relaxng.h
@@ -32,7 +32,7 @@
  *
  * Signature of an error callback from a Relax-NG validation
  */
-typedef void (XMLCDECL *xmlRelaxNGValidityErrorFunc) (void *ctx, const char *msg, ...) ATTRIBUTE_PRINTF(2,3);
+typedef void (XMLCDECL *xmlRelaxNGValidityErrorFunc) (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
 
 /**
  * xmlRelaxNGValidityWarningFunc:
@@ -42,7 +42,7 @@
  *
  * Signature of a warning callback from a Relax-NG validation
  */
-typedef void (XMLCDECL *xmlRelaxNGValidityWarningFunc) (void *ctx, const char *msg, ...) ATTRIBUTE_PRINTF(2,3);
+typedef void (XMLCDECL *xmlRelaxNGValidityWarningFunc) (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
 
 /**
  * A schemas validation context
diff --git a/include/libxml/valid.h b/include/libxml/valid.h
index f1892b0..a2307f1 100644
--- a/include/libxml/valid.h
+++ b/include/libxml/valid.h
@@ -41,7 +41,7 @@
  */
 typedef void (XMLCDECL *xmlValidityErrorFunc) (void *ctx,
 			     const char *msg,
-			     ...) ATTRIBUTE_PRINTF(2,3);
+			     ...) LIBXML_ATTR_FORMAT(2,3);
 
 /**
  * xmlValidityWarningFunc:
@@ -56,7 +56,7 @@
  */
 typedef void (XMLCDECL *xmlValidityWarningFunc) (void *ctx,
 			       const char *msg,
-			       ...) ATTRIBUTE_PRINTF(2,3);
+			       ...) LIBXML_ATTR_FORMAT(2,3);
 
 #ifdef IN_LIBXML
 /**
diff --git a/include/libxml/xinclude.h b/include/libxml/xinclude.h
index ba9c9b5..863ab25 100644
--- a/include/libxml/xinclude.h
+++ b/include/libxml/xinclude.h
@@ -89,18 +89,22 @@
 /*
  * standalone processing
  */
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN int XMLCALL
 		xmlXIncludeProcess	(xmlDocPtr doc);
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN int XMLCALL
 		xmlXIncludeProcessFlags	(xmlDocPtr doc,
 					 int flags);
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN int XMLCALL
 		xmlXIncludeProcessFlagsData(xmlDocPtr doc,
 					 int flags,
 					 void *data);
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN int XMLCALL
+                xmlXIncludeProcessTreeFlagsData(xmlNodePtr tree,
+                                         int flags,
+                                         void *data);
+XMLPUBFUN int XMLCALL
 		xmlXIncludeProcessTree	(xmlNodePtr tree);
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN int XMLCALL
 		xmlXIncludeProcessTreeFlags(xmlNodePtr tree,
 					 int flags);
 /*
diff --git a/include/libxml/xmlerror.h b/include/libxml/xmlerror.h
index 7cce9c3..e924211 100644
--- a/include/libxml/xmlerror.h
+++ b/include/libxml/xmlerror.h
@@ -843,7 +843,7 @@
  */
 typedef void (XMLCDECL *xmlGenericErrorFunc) (void *ctx,
 				 const char *msg,
-				 ...) ATTRIBUTE_PRINTF(2,3);
+				 ...) LIBXML_ATTR_FORMAT(2,3);
 /**
  * xmlStructuredErrorFunc:
  * @userData:  user provided data for the error callback
@@ -874,19 +874,19 @@
 XMLPUBFUN void XMLCDECL
     xmlParserError		(void *ctx,
 				 const char *msg,
-				 ...) ATTRIBUTE_PRINTF(2,3);
+				 ...) LIBXML_ATTR_FORMAT(2,3);
 XMLPUBFUN void XMLCDECL
     xmlParserWarning		(void *ctx,
 				 const char *msg,
-				 ...) ATTRIBUTE_PRINTF(2,3);
+				 ...) LIBXML_ATTR_FORMAT(2,3);
 XMLPUBFUN void XMLCDECL
     xmlParserValidityError	(void *ctx,
 				 const char *msg,
-				 ...) ATTRIBUTE_PRINTF(2,3);
+				 ...) LIBXML_ATTR_FORMAT(2,3);
 XMLPUBFUN void XMLCDECL
     xmlParserValidityWarning	(void *ctx,
 				 const char *msg,
-				 ...) ATTRIBUTE_PRINTF(2,3);
+				 ...) LIBXML_ATTR_FORMAT(2,3);
 XMLPUBFUN void XMLCALL
     xmlParserPrintFileInfo	(xmlParserInputPtr input);
 XMLPUBFUN void XMLCALL
@@ -930,7 +930,7 @@
 				 int int1,
 				 int col,
 				 const char *msg,
-				 ...) ATTRIBUTE_PRINTF(16,17);
+				 ...) LIBXML_ATTR_FORMAT(16,17);
 XMLPUBFUN void XMLCALL
     __xmlSimpleError		(int domain,
 				 int code,
diff --git a/include/libxml/xmlexports.h b/include/libxml/xmlexports.h
index 29a6f54..9c6790c 100644
--- a/include/libxml/xmlexports.h
+++ b/include/libxml/xmlexports.h
@@ -108,6 +108,11 @@
   #undef XMLPUBVAR
   #undef XMLCALL
   #undef XMLCDECL
+  /*
+   * if defined(IN_LIBXML) this raises problems on mingw with msys
+   * _imp__xmlFree listed as missing. Try to workaround the problem
+   * by also making that declaration when compiling client code.
+   */
   #if defined(IN_LIBXML) && !defined(LIBXML_STATIC)
     #define XMLPUBFUN __declspec(dllexport)
     #define XMLPUBVAR __declspec(dllexport)
diff --git a/include/libxml/xmlmemory.h b/include/libxml/xmlmemory.h
index 8f3b109..17e375a 100644
--- a/include/libxml/xmlmemory.h
+++ b/include/libxml/xmlmemory.h
@@ -63,7 +63,7 @@
  *
  * Returns a pointer to the newly allocated block or NULL in case of error.
  */
-typedef void *(ATTRIBUTE_ALLOC_SIZE(1) XMLCALL *xmlMallocFunc)(size_t size);
+typedef void *(LIBXML_ATTR_ALLOC_SIZE(1) XMLCALL *xmlMallocFunc)(size_t size);
 
 /**
  * xmlReallocFunc:
@@ -88,11 +88,11 @@
 
 /*
  * The 4 interfaces used for all memory handling within libxml.
-LIBXML_DLL_IMPORT extern xmlFreeFunc xmlFree;
-LIBXML_DLL_IMPORT extern xmlMallocFunc xmlMalloc;
-LIBXML_DLL_IMPORT extern xmlMallocFunc xmlMallocAtomic;
-LIBXML_DLL_IMPORT extern xmlReallocFunc xmlRealloc;
-LIBXML_DLL_IMPORT extern xmlStrdupFunc xmlMemStrdup;
+LIBXML_DLL_IMPORT xmlFreeFunc xmlFree;
+LIBXML_DLL_IMPORT xmlMallocFunc xmlMalloc;
+LIBXML_DLL_IMPORT xmlMallocFunc xmlMallocAtomic;
+LIBXML_DLL_IMPORT xmlReallocFunc xmlRealloc;
+LIBXML_DLL_IMPORT xmlStrdupFunc xmlMemStrdup;
  */
 
 /*
@@ -150,7 +150,7 @@
 XMLPUBFUN void XMLCALL
 	xmlMemoryDump	(void);
 XMLPUBFUN void * XMLCALL
-	xmlMemMalloc	(size_t size) ATTRIBUTE_ALLOC_SIZE(1);
+	xmlMemMalloc	(size_t size) LIBXML_ATTR_ALLOC_SIZE(1);
 XMLPUBFUN void * XMLCALL
 	xmlMemRealloc	(void *ptr,size_t size);
 XMLPUBFUN void XMLCALL
@@ -158,11 +158,11 @@
 XMLPUBFUN char * XMLCALL
 	xmlMemoryStrdup	(const char *str);
 XMLPUBFUN void * XMLCALL
-	xmlMallocLoc	(size_t size, const char *file, int line) ATTRIBUTE_ALLOC_SIZE(1);
+	xmlMallocLoc	(size_t size, const char *file, int line) LIBXML_ATTR_ALLOC_SIZE(1);
 XMLPUBFUN void * XMLCALL
 	xmlReallocLoc	(void *ptr, size_t size, const char *file, int line);
 XMLPUBFUN void * XMLCALL
-	xmlMallocAtomicLoc (size_t size, const char *file, int line) ATTRIBUTE_ALLOC_SIZE(1);
+	xmlMallocAtomicLoc (size_t size, const char *file, int line) LIBXML_ATTR_ALLOC_SIZE(1);
 XMLPUBFUN char * XMLCALL
 	xmlMemStrdupLoc	(const char *str, const char *file, int line);
 
diff --git a/include/libxml/xmlsave.h b/include/libxml/xmlsave.h
index 4201b4d..fb329b2 100644
--- a/include/libxml/xmlsave.h
+++ b/include/libxml/xmlsave.h
@@ -33,7 +33,8 @@
     XML_SAVE_NO_XHTML	= 1<<3, /* disable XHTML1 specific rules */
     XML_SAVE_XHTML	= 1<<4, /* force XHTML1 specific rules */
     XML_SAVE_AS_XML     = 1<<5, /* force XML serialization on HTML doc */
-    XML_SAVE_AS_HTML    = 1<<6  /* force HTML serialization on XML doc */
+    XML_SAVE_AS_HTML    = 1<<6, /* force HTML serialization on XML doc */
+    XML_SAVE_WSNONSIG   = 1<<7  /* format with non-significant whitespace */
 } xmlSaveOption;
 
 
diff --git a/include/libxml/xmlschemas.h b/include/libxml/xmlschemas.h
index ebef3a7..752bc3a 100644
--- a/include/libxml/xmlschemas.h
+++ b/include/libxml/xmlschemas.h
@@ -92,7 +92,7 @@
  *
  * Signature of an error callback from an XSD validation
  */
-typedef void (XMLCDECL *xmlSchemaValidityErrorFunc) (void *ctx, const char *msg, ...) ATTRIBUTE_PRINTF(2,3);
+typedef void (XMLCDECL *xmlSchemaValidityErrorFunc) (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
 
 /**
  * xmlSchemaValidityWarningFunc:
@@ -102,7 +102,7 @@
  *
  * Signature of a warning callback from an XSD validation
  */
-typedef void (XMLCDECL *xmlSchemaValidityWarningFunc) (void *ctx, const char *msg, ...) ATTRIBUTE_PRINTF(2,3);
+typedef void (XMLCDECL *xmlSchemaValidityWarningFunc) (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
 
 /**
  * A schemas validation context
diff --git a/include/libxml/xmlstring.h b/include/libxml/xmlstring.h
index 1dfc5ea..0bc6888 100644
--- a/include/libxml/xmlstring.h
+++ b/include/libxml/xmlstring.h
@@ -59,7 +59,7 @@
                                          const xmlChar *val);
 XMLPUBFUN const xmlChar * XMLCALL
                 xmlStrcasestr            (const xmlChar *str,
-                                         xmlChar *val);
+                                         const xmlChar *val);
 XMLPUBFUN int XMLCALL
                 xmlStrcmp                (const xmlChar *str1,
                                          const xmlChar *str2);
diff --git a/include/libxml/xmlversion.h b/include/libxml/xmlversion.h
index d98f5b0..9e6f66b 100644
--- a/include/libxml/xmlversion.h
+++ b/include/libxml/xmlversion.h
@@ -29,28 +29,28 @@
  *
  * the version string like "1.2.3"
  */
-#define LIBXML_DOTTED_VERSION "2.7.3"
+#define LIBXML_DOTTED_VERSION "2.7.8"
 
 /**
  * LIBXML_VERSION:
  *
  * the version number: 1.2.3 value is 10203
  */
-#define LIBXML_VERSION 20703
+#define LIBXML_VERSION 20708
 
 /**
  * LIBXML_VERSION_STRING:
  *
  * the version number string, 1.2.3 value is "10203"
  */
-#define LIBXML_VERSION_STRING "20703"
+#define LIBXML_VERSION_STRING "20708"
 
 /**
  * LIBXML_VERSION_EXTRA:
  *
  * extra version information, used to show a CVS compilation
  */
-#define LIBXML_VERSION_EXTRA ""
+#define LIBXML_VERSION_EXTRA "-GITv2.7.8-56-g8973d58"
 
 /**
  * LIBXML_TEST_VERSION:
@@ -58,7 +58,7 @@
  * Macro to check that the libxml version in use is compatible with
  * the version the software has been compiled against
  */
-#define LIBXML_TEST_VERSION xmlCheckVersion(20703);
+#define LIBXML_TEST_VERSION xmlCheckVersion(20708);
 
 #ifndef VMS
 #if 0
@@ -391,6 +391,15 @@
 #define LIBXML_ZLIB_ENABLED
 #endif
 
+/**
+ * LIBXML_LZMA_ENABLED:
+ *
+ * Whether the Lzma support is compiled in
+ */
+#if 0
+#define LIBXML_LZMA_ENABLED
+#endif
+
 #ifdef __GNUC__
 #ifdef HAVE_ANSIDECL_H
 #include <ansidecl.h>
@@ -407,35 +416,35 @@
 #endif
 
 /**
- * ATTRIBUTE_ALLOC_SIZE:
+ * LIBXML_ATTR_ALLOC_SIZE:
  *
  * Macro used to indicate to GCC this is an allocator function
  */
 
-#ifndef ATTRIBUTE_ALLOC_SIZE
+#ifndef LIBXML_ATTR_ALLOC_SIZE
 # if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))
-#  define ATTRIBUTE_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
+#  define LIBXML_ATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
 # else
-#  define ATTRIBUTE_ALLOC_SIZE(x)
+#  define LIBXML_ATTR_ALLOC_SIZE(x)
 # endif
 #else
-# define ATTRIBUTE_ALLOC_SIZE(x)
+# define LIBXML_ATTR_ALLOC_SIZE(x)
 #endif
 
 /**
- * ATTRIBUTE_PRINTF:
+ * LIBXML_ATTR_FORMAT:
  *
  * Macro used to indicate to GCC the parameter are printf like
  */
 
-#ifndef ATTRIBUTE_PRINTF
+#ifndef LIBXML_ATTR_FORMAT
 # if ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)))
-#  define ATTRIBUTE_PRINTF(fmt,args) __attribute__((__format__(__printf__,fmt,args)))
+#  define LIBXML_ATTR_FORMAT(fmt,args) __attribute__((__format__(__printf__,fmt,args)))
 # else
-#  define ATTRIBUTE_PRINTF(fmt,args)
+#  define LIBXML_ATTR_FORMAT(fmt,args)
 # endif
 #else
-# define ATTRIBUTE_PRINTF(fmt,args)
+# define LIBXML_ATTR_FORMAT(fmt,args)
 #endif
 
 #else /* ! __GNUC__ */
@@ -446,20 +455,22 @@
  */
 #define ATTRIBUTE_UNUSED
 /**
- * ATTRIBUTE_ALLOC_SIZE:
+ * LIBXML_ATTR_ALLOC_SIZE:
  *
  * Macro used to indicate to GCC this is an allocator function
  */
-#define ATTRIBUTE_ALLOC_SIZE(x)
+#define LIBXML_ATTR_ALLOC_SIZE(x)
 /**
- * ATTRIBUTE_PRINTF:
+ * LIBXML_ATTR_FORMAT:
  *
  * Macro used to indicate to GCC the parameter are printf like
  */
-#define ATTRIBUTE_PRINTF(fmt,args)
+#define LIBXML_ATTR_FORMAT(fmt,args)
 #endif /* __GNUC__ */
 
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 #endif
+
+
diff --git a/include/libxml/xmlwriter.h b/include/libxml/xmlwriter.h
index df4509d..91e683c 100644
--- a/include/libxml/xmlwriter.h
+++ b/include/libxml/xmlwriter.h
@@ -70,12 +70,12 @@
     XMLPUBFUN int XMLCALL
         xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
                                         const char *format, ...)
-					ATTRIBUTE_PRINTF(2,3);
+					LIBXML_ATTR_FORMAT(2,3);
     XMLPUBFUN int XMLCALL
         xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
                                          const char *format,
                                          va_list argptr)
-					 ATTRIBUTE_PRINTF(2,0);
+					 LIBXML_ATTR_FORMAT(2,0);
     XMLPUBFUN int XMLCALL xmlTextWriterWriteComment(xmlTextWriterPtr
                                                     writer,
                                                     const xmlChar *
@@ -105,13 +105,13 @@
         xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
                                         const xmlChar * name,
                                         const char *format, ...)
-					ATTRIBUTE_PRINTF(3,4);
+					LIBXML_ATTR_FORMAT(3,4);
     XMLPUBFUN int XMLCALL
         xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
                                          const xmlChar * name,
                                          const char *format,
                                          va_list argptr)
-					 ATTRIBUTE_PRINTF(3,0);
+					 LIBXML_ATTR_FORMAT(3,0);
     XMLPUBFUN int XMLCALL xmlTextWriterWriteElement(xmlTextWriterPtr
                                                     writer,
                                                     const xmlChar * name,
@@ -123,7 +123,7 @@
                                           const xmlChar * name,
                                           const xmlChar * namespaceURI,
                                           const char *format, ...)
-					  ATTRIBUTE_PRINTF(5,6);
+					  LIBXML_ATTR_FORMAT(5,6);
     XMLPUBFUN int XMLCALL
         xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
                                            const xmlChar * prefix,
@@ -131,7 +131,7 @@
                                            const xmlChar * namespaceURI,
                                            const char *format,
                                            va_list argptr)
-					   ATTRIBUTE_PRINTF(5,0);
+					   LIBXML_ATTR_FORMAT(5,0);
     XMLPUBFUN int XMLCALL xmlTextWriterWriteElementNS(xmlTextWriterPtr
                                                       writer,
                                                       const xmlChar *
@@ -148,11 +148,11 @@
     XMLPUBFUN int XMLCALL
         xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer,
                                     const char *format, ...)
-				    ATTRIBUTE_PRINTF(2,3);
+				    LIBXML_ATTR_FORMAT(2,3);
     XMLPUBFUN int XMLCALL
         xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer,
                                      const char *format, va_list argptr)
-				     ATTRIBUTE_PRINTF(2,0);
+				     LIBXML_ATTR_FORMAT(2,0);
     XMLPUBFUN int XMLCALL
         xmlTextWriterWriteRawLen(xmlTextWriterPtr writer,
                                  const xmlChar * content, int len);
@@ -163,13 +163,13 @@
                                                          writer,
                                                          const char
                                                          *format, ...)
-							 ATTRIBUTE_PRINTF(2,3);
+							 LIBXML_ATTR_FORMAT(2,3);
     XMLPUBFUN int XMLCALL xmlTextWriterWriteVFormatString(xmlTextWriterPtr
                                                           writer,
                                                           const char
                                                           *format,
                                                           va_list argptr)
-							  ATTRIBUTE_PRINTF(2,0);
+							  LIBXML_ATTR_FORMAT(2,0);
     XMLPUBFUN int XMLCALL xmlTextWriterWriteString(xmlTextWriterPtr writer,
                                                    const xmlChar *
                                                    content);
@@ -204,13 +204,13 @@
         xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
                                           const xmlChar * name,
                                           const char *format, ...)
-					  ATTRIBUTE_PRINTF(3,4);
+					  LIBXML_ATTR_FORMAT(3,4);
     XMLPUBFUN int XMLCALL
         xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
                                            const xmlChar * name,
                                            const char *format,
                                            va_list argptr)
-					   ATTRIBUTE_PRINTF(3,0);
+					   LIBXML_ATTR_FORMAT(3,0);
     XMLPUBFUN int XMLCALL xmlTextWriterWriteAttribute(xmlTextWriterPtr
                                                       writer,
                                                       const xmlChar * name,
@@ -222,7 +222,7 @@
                                             const xmlChar * name,
                                             const xmlChar * namespaceURI,
                                             const char *format, ...)
-					    ATTRIBUTE_PRINTF(5,6);
+					    LIBXML_ATTR_FORMAT(5,6);
     XMLPUBFUN int XMLCALL
         xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
                                              const xmlChar * prefix,
@@ -230,7 +230,7 @@
                                              const xmlChar * namespaceURI,
                                              const char *format,
                                              va_list argptr)
-					     ATTRIBUTE_PRINTF(5,0);
+					     LIBXML_ATTR_FORMAT(5,0);
     XMLPUBFUN int XMLCALL xmlTextWriterWriteAttributeNS(xmlTextWriterPtr
                                                         writer,
                                                         const xmlChar *
@@ -257,12 +257,12 @@
         xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer,
                                    const xmlChar * target,
                                    const char *format, ...)
-				   ATTRIBUTE_PRINTF(3,4);
+				   LIBXML_ATTR_FORMAT(3,4);
     XMLPUBFUN int XMLCALL
         xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
                                     const xmlChar * target,
                                     const char *format, va_list argptr)
-				    ATTRIBUTE_PRINTF(3,0);
+				    LIBXML_ATTR_FORMAT(3,0);
     XMLPUBFUN int XMLCALL
         xmlTextWriterWritePI(xmlTextWriterPtr writer,
                              const xmlChar * target,
@@ -287,11 +287,11 @@
     XMLPUBFUN int XMLCALL
         xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer,
                                       const char *format, ...)
-				      ATTRIBUTE_PRINTF(2,3);
+				      LIBXML_ATTR_FORMAT(2,3);
     XMLPUBFUN int XMLCALL
         xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer,
                                        const char *format, va_list argptr)
-				       ATTRIBUTE_PRINTF(2,0);
+				       LIBXML_ATTR_FORMAT(2,0);
     XMLPUBFUN int XMLCALL
         xmlTextWriterWriteCDATA(xmlTextWriterPtr writer,
                                 const xmlChar * content);
@@ -315,14 +315,14 @@
                                     const xmlChar * pubid,
                                     const xmlChar * sysid,
                                     const char *format, ...)
-				    ATTRIBUTE_PRINTF(5,6);
+				    LIBXML_ATTR_FORMAT(5,6);
     XMLPUBFUN int XMLCALL
         xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
                                      const xmlChar * name,
                                      const xmlChar * pubid,
                                      const xmlChar * sysid,
                                      const char *format, va_list argptr)
-				     ATTRIBUTE_PRINTF(5,0);
+				     LIBXML_ATTR_FORMAT(5,0);
     XMLPUBFUN int XMLCALL
         xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
                               const xmlChar * name,
@@ -353,13 +353,13 @@
         xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
                                            const xmlChar * name,
                                            const char *format, ...)
-					   ATTRIBUTE_PRINTF(3,4);
+					   LIBXML_ATTR_FORMAT(3,4);
     XMLPUBFUN int XMLCALL
         xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
                                             const xmlChar * name,
                                             const char *format,
                                             va_list argptr)
-					    ATTRIBUTE_PRINTF(3,0);
+					    LIBXML_ATTR_FORMAT(3,0);
     XMLPUBFUN int XMLCALL xmlTextWriterWriteDTDElement(xmlTextWriterPtr
                                                        writer,
                                                        const xmlChar *
@@ -383,13 +383,13 @@
         xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
                                            const xmlChar * name,
                                            const char *format, ...)
-					   ATTRIBUTE_PRINTF(3,4);
+					   LIBXML_ATTR_FORMAT(3,4);
     XMLPUBFUN int XMLCALL
         xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
                                             const xmlChar * name,
                                             const char *format,
                                             va_list argptr)
-					    ATTRIBUTE_PRINTF(3,0);
+					    LIBXML_ATTR_FORMAT(3,0);
     XMLPUBFUN int XMLCALL xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr
                                                        writer,
                                                        const xmlChar *
@@ -414,14 +414,14 @@
                                                   int pe,
                                                   const xmlChar * name,
                                                   const char *format, ...)
-						  ATTRIBUTE_PRINTF(4,5);
+						  LIBXML_ATTR_FORMAT(4,5);
     XMLPUBFUN int XMLCALL
         xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
                                                    int pe,
                                                    const xmlChar * name,
                                                    const char *format,
                                                    va_list argptr)
-						   ATTRIBUTE_PRINTF(4,0);
+						   LIBXML_ATTR_FORMAT(4,0);
     XMLPUBFUN int XMLCALL
         xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
                                             int pe,
diff --git a/include/libxml/xpath.h b/include/libxml/xpath.h
index 1a9e30e..ddd9dd8 100644
--- a/include/libxml/xpath.h
+++ b/include/libxml/xpath.h
@@ -68,7 +68,8 @@
     XPATH_UNDEF_PREFIX_ERROR,
     XPATH_ENCODING_ERROR,
     XPATH_INVALID_CHAR_ERROR,
-    XPATH_INVALID_CTXT
+    XPATH_INVALID_CTXT,
+    XPATH_STACK_ERROR
 } xmlXPathError;
 
 /*
@@ -380,6 +381,8 @@
     xmlXPathCompExprPtr comp;		/* the precompiled expression */
     int xptr;				/* it this an XPointer expression */
     xmlNodePtr         ancestor;	/* used for walking preceding axis */
+
+    int              valueFrame;        /* used to limit Pop on the stack */
 };
 
 /************************************************************************
diff --git a/libxml.h b/libxml.h
index 3c44c83..dfc6c64 100644
--- a/libxml.h
+++ b/libxml.h
@@ -90,4 +90,7 @@
 #endif
 #endif
 #endif
+#if !defined(PIC) && !defined(NOLIBTOOL)
+#  define LIBXML_STATIC
+#endif
 #endif /* ! __XML_LIBXML_H__ */
diff --git a/nanoftp.c b/nanoftp.c
index a54b85b..a7ca5b6 100644
--- a/nanoftp.c
+++ b/nanoftp.c
@@ -78,7 +78,9 @@
 
 
 #if defined(__MINGW32__) || defined(_WIN32_WCE)
+#ifndef _WINSOCKAPI_
 #define _WINSOCKAPI_
+#endif
 #include <wsockcompat.h>
 #include <winsock2.h>
 #undef XML_SOCKLEN_T
@@ -92,7 +94,6 @@
 #if !defined(__BEOS__) || defined(__HAIKU__)
 #define closesocket(s) close(s)
 #endif
-#define SOCKET int
 #endif
 
 #ifdef __BEOS__
@@ -484,7 +485,7 @@
     ret->returnValue = 0;
     ret->controlBufIndex = 0;
     ret->controlBufUsed = 0;
-    ret->controlFd = -1;
+    ret->controlFd = INVALID_SOCKET;
 
     unescaped = xmlURIUnescapeString(URL, 0, NULL);
     if (unescaped != NULL) {
@@ -511,8 +512,8 @@
     if (ctxt->protocol != NULL) xmlFree(ctxt->protocol);
     if (ctxt->path != NULL) xmlFree(ctxt->path);
     ctxt->passive = 1;
-    if (ctxt->controlFd >= 0) closesocket(ctxt->controlFd);
-    ctxt->controlFd = -1;
+    if (ctxt->controlFd != INVALID_SOCKET) closesocket(ctxt->controlFd);
+    ctxt->controlFd = INVALID_SOCKET;
     ctxt->controlBufIndex = -1;
     ctxt->controlBufUsed = -1;
     xmlFree(ctxt);
@@ -567,7 +568,7 @@
     int len;
     int size;
 
-    if ((ctxt == NULL) || (ctxt->controlFd < 0)) return(-1);
+    if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
 
     if ((ctxt->controlBufIndex < 0) || (ctxt->controlBufIndex > FTP_BUF_SIZE)) {
 #ifdef DEBUG_FTP
@@ -619,8 +620,8 @@
     if ((len = recv(ctxt->controlFd, &ctxt->controlBuf[ctxt->controlBufIndex],
 		    size, 0)) < 0) {
 	__xmlIOErr(XML_FROM_FTP, 0, "recv failed");
-	closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-        ctxt->controlFd = -1;
+	closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+        ctxt->controlFd = INVALID_SOCKET;
         return(-1);
     }
 #ifdef DEBUG_FTP
@@ -648,7 +649,7 @@
     int len;
     int res = -1, cur = -1;
 
-    if ((ctxt == NULL) || (ctxt->controlFd < 0)) return(-1);
+    if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
 
 get_more:
     /*
@@ -737,7 +738,7 @@
     fd_set rfd;
     struct timeval tv;
 
-    if ((ctxt == NULL) || (ctxt->controlFd < 0)) return(-1);
+    if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
     tv.tv_sec = 0;
     tv.tv_usec = 0;
     FD_ZERO(&rfd);
@@ -826,7 +827,7 @@
     char buf[200];
     int len, res;
 
-    if ((ctxt == NULL) || (ctxt->controlFd < 0)) return(-1);
+    if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
 
     snprintf(buf, sizeof(buf), "QUIT\r\n");
     len = strlen(buf);
@@ -951,7 +952,7 @@
 	addrlen = sizeof (struct sockaddr_in);
     }
 
-    if (ctxt->controlFd < 0) {
+    if (ctxt->controlFd == INVALID_SOCKET) {
 	__xmlIOErr(XML_FROM_FTP, 0, "socket failed");
         return(-1);
     }
@@ -962,8 +963,8 @@
     if (connect(ctxt->controlFd, (struct sockaddr *) &ctxt->ftpAddr,
 	    addrlen) < 0) {
 	__xmlIOErr(XML_FROM_FTP, 0, "Failed to create a connection");
-        closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-        ctxt->controlFd = -1;
+        closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+        ctxt->controlFd = INVALID_SOCKET;
 	return(-1);
     }
 
@@ -972,8 +973,8 @@
      */
     res = xmlNanoFTPGetResponse(ctxt);
     if (res != 2) {
-        closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-        ctxt->controlFd = -1;
+        closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+        ctxt->controlFd = INVALID_SOCKET;
 	return(-1);
     }
 
@@ -1030,7 +1031,7 @@
 	    if (res < 0) {
 		__xmlIOErr(XML_FROM_FTP, 0, "send failed");
 		closesocket(ctxt->controlFd);
-		ctxt->controlFd = -1;
+		ctxt->controlFd = INVALID_SOCKET;
 	        return(res);
 	    }
 	    res = xmlNanoFTPGetResponse(ctxt);
@@ -1052,13 +1053,13 @@
 		    if (res < 0) {
 			__xmlIOErr(XML_FROM_FTP, 0, "send failed");
 			closesocket(ctxt->controlFd);
-			ctxt->controlFd = -1;
+			ctxt->controlFd = INVALID_SOCKET;
 			return(res);
 		    }
 		    res = xmlNanoFTPGetResponse(ctxt);
 		    if (res > 3) {
 			closesocket(ctxt->controlFd);
-			ctxt->controlFd = -1;
+			ctxt->controlFd = INVALID_SOCKET;
 			return(-1);
 		    }
 		    break;
@@ -1069,7 +1070,7 @@
 		case -1:
 		default:
 		    closesocket(ctxt->controlFd);
-		    ctxt->controlFd = -1;
+		    ctxt->controlFd = INVALID_SOCKET;
 		    return(-1);
 	    }
 	}
@@ -1092,8 +1093,8 @@
 		res = send(ctxt->controlFd, buf, len, 0);
 		if (res < 0) {
 		    __xmlIOErr(XML_FROM_FTP, 0, "send failed");
-		    closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-		    ctxt->controlFd = -1;
+		    closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+		    ctxt->controlFd = INVALID_SOCKET;
 		    return(res);
 		}
 		res = xmlNanoFTPGetResponse(ctxt);
@@ -1103,8 +1104,8 @@
 		    break;
 		}    
 		if (proxyType == 1) {
-		    closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-		    ctxt->controlFd = -1;
+		    closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+		    ctxt->controlFd = INVALID_SOCKET;
 		    return(-1);
 		}
 	    case 2:
@@ -1123,8 +1124,8 @@
 		res = send(ctxt->controlFd, buf, len, 0);
 		if (res < 0) {
 		    __xmlIOErr(XML_FROM_FTP, 0, "send failed");
-		    closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-		    ctxt->controlFd = -1;
+		    closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+		    ctxt->controlFd = INVALID_SOCKET;
 		    return(res);
 		}
 		res = xmlNanoFTPGetResponse(ctxt);
@@ -1145,8 +1146,8 @@
 		res = send(ctxt->controlFd, buf, len, 0);
 		if (res < 0) {
 		    __xmlIOErr(XML_FROM_FTP, 0, "send failed");
-		    closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-		    ctxt->controlFd = -1;
+		    closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+		    ctxt->controlFd = INVALID_SOCKET;
 		    return(res);
 		}
 		res = xmlNanoFTPGetResponse(ctxt);
@@ -1156,8 +1157,8 @@
 		    return(0);
 		}
 		if (proxyType == 2) {
-		    closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-		    ctxt->controlFd = -1;
+		    closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+		    ctxt->controlFd = INVALID_SOCKET;
 		    return(-1);
 		}
 	    case 3:
@@ -1166,8 +1167,8 @@
 		 * send the code or at least the sequence in use.
 		 */
 	    default:
-		closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-		ctxt->controlFd = -1;
+		closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+		ctxt->controlFd = INVALID_SOCKET;
 		return(-1);
 	}
     }
@@ -1176,8 +1177,8 @@
      */
     res = xmlNanoFTPSendUser(ctxt);
     if (res < 0) {
-        closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-        ctxt->controlFd = -1;
+        closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+        ctxt->controlFd = INVALID_SOCKET;
 	return(-1);
     }
     res = xmlNanoFTPGetResponse(ctxt);
@@ -1191,14 +1192,14 @@
 	case 5:
         case -1:
 	default:
-	    closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-	    ctxt->controlFd = -1;
+	    closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+	    ctxt->controlFd = INVALID_SOCKET;
 	    return(-1);
     }
     res = xmlNanoFTPSendPasswd(ctxt);
     if (res < 0) {
-        closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-        ctxt->controlFd = -1;
+        closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+        ctxt->controlFd = INVALID_SOCKET;
 	return(-1);
     }
     res = xmlNanoFTPGetResponse(ctxt);
@@ -1213,8 +1214,8 @@
 	case 5:
         case -1:
 	default:
-	    closesocket(ctxt->controlFd); ctxt->controlFd = -1;
-	    ctxt->controlFd = -1;
+	    closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+	    ctxt->controlFd = INVALID_SOCKET;
 	    return(-1);
     }
 
@@ -1270,7 +1271,7 @@
     int len;
     int res;
 
-    if ((ctxt == NULL) || (ctxt->controlFd < 0)) return(-1);
+    if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
     if (directory == NULL) return 0;
 
     /*
@@ -1319,7 +1320,7 @@
     int len;
     int res;
 
-    if ((ctxt == NULL) || (ctxt->controlFd < 0) || (file == NULL)) return(-1);
+    if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET) || (file == NULL)) return(-1);
     if (file == NULL) return (0);
 
     /*
@@ -1362,7 +1363,7 @@
  * Returns -1 incase of error, 0 otherwise
  */
 
-int
+SOCKET
 xmlNanoFTPGetConnection(void *ctx) {
     xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
     char buf[200], *cur;
@@ -1377,7 +1378,7 @@
 #endif
     XML_SOCKLEN_T dataAddrLen;
 
-    if (ctxt == NULL) return(-1);
+    if (ctxt == NULL) return INVALID_SOCKET;
 
     memset (&dataAddr, 0, sizeof(dataAddr));
 #ifdef SUPPORT_IP6
@@ -1393,9 +1394,9 @@
 	dataAddrLen = sizeof (struct sockaddr_in);
     }
 
-    if (ctxt->dataFd < 0) {
+    if (ctxt->dataFd == INVALID_SOCKET) {
 	__xmlIOErr(XML_FROM_FTP, 0, "socket failed");
-	return (-1);
+	return INVALID_SOCKET;
     }
 
     if (ctxt->passive) {
@@ -1412,19 +1413,19 @@
 	res = send(ctxt->controlFd, buf, len, 0);
 	if (res < 0) {
 	    __xmlIOErr(XML_FROM_FTP, 0, "send failed");
-	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-	    return(res);
+	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+	    return INVALID_SOCKET;
 	}
         res = xmlNanoFTPReadResponse(ctx);
 	if (res != 2) {
 	    if (res == 5) {
-	        closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-		return(-1);
+	        closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+		return INVALID_SOCKET;
 	    } else {
 		/*
 		 * retry with an active connection
 		 */
-	        closesocket(ctxt->dataFd); ctxt->dataFd = -1;
+	        closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
 	        ctxt->passive = 0;
 	    }
 	}
@@ -1435,10 +1436,10 @@
 	    if (sscanf (cur, "%u", &temp[0]) != 1) {
 		__xmlIOErr(XML_FROM_FTP, XML_FTP_EPSV_ANSWER,
 			"Invalid answer to EPSV\n");
-		if (ctxt->dataFd != -1) {
-		    closesocket (ctxt->dataFd); ctxt->dataFd = -1;
+		if (ctxt->dataFd != INVALID_SOCKET) {
+		    closesocket (ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
 		}
-		return (-1);
+		return INVALID_SOCKET;
 	    }
 	    memcpy (&((struct sockaddr_in6 *)&dataAddr)->sin6_addr, &((struct sockaddr_in6 *)&ctxt->ftpAddr)->sin6_addr, sizeof(struct in6_addr));
 	    ((struct sockaddr_in6 *)&dataAddr)->sin6_port = htons (temp[0]);
@@ -1450,10 +1451,10 @@
 		&temp[3], &temp[4], &temp[5]) != 6) {
 		__xmlIOErr(XML_FROM_FTP, XML_FTP_PASV_ANSWER,
 			"Invalid answer to PASV\n");
-		if (ctxt->dataFd != -1) {
-		    closesocket (ctxt->dataFd); ctxt->dataFd = -1;
+		if (ctxt->dataFd != INVALID_SOCKET) {
+		    closesocket (ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
 		}
-		return (-1);
+		return INVALID_SOCKET;
 	    }
 	    for (i=0; i<6; i++) ad[i] = (unsigned char) (temp[i] & 0xff);
 	    memcpy (&((struct sockaddr_in *)&dataAddr)->sin_addr, &ad[0], 4);
@@ -1462,8 +1463,8 @@
 
 	if (connect(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) {
 	    __xmlIOErr(XML_FROM_FTP, 0, "Failed to create a data connection");
-	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-	    return (-1);
+	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+	    return INVALID_SOCKET;
 	}
     } else {
         getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen);
@@ -1476,15 +1477,15 @@
 
 	if (bind(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) {
 	    __xmlIOErr(XML_FROM_FTP, 0, "bind failed");
-	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-	    return (-1);
+	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+	    return INVALID_SOCKET;
 	}
         getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen);
 
 	if (listen(ctxt->dataFd, 1) < 0) {
 	    __xmlIOErr(XML_FROM_FTP, 0, "listen failed");
-	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-	    return (-1);
+	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+	    return INVALID_SOCKET;
 	}
 #ifdef SUPPORT_IP6
 	if ((ctxt->ftpAddr).ss_family == AF_INET6) {
@@ -1513,13 +1514,13 @@
 	res = send(ctxt->controlFd, buf, len, 0);
 	if (res < 0) {
 	    __xmlIOErr(XML_FROM_FTP, 0, "send failed");
-	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-	    return(res);
+	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+	    return INVALID_SOCKET;
 	}
         res = xmlNanoFTPGetResponse(ctxt);
 	if (res != 2) {
-	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-	    return(-1);
+	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+	    return INVALID_SOCKET;
         }
     }
     return(ctxt->dataFd);
@@ -1542,9 +1543,9 @@
     fd_set rfd, efd;
     struct timeval tv;
 
-    if ((ctxt == NULL) || (ctxt->controlFd < 0)) return(-1);
+    if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
 
-    closesocket(ctxt->dataFd); ctxt->dataFd = -1;
+    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
     tv.tv_sec = 15;
     tv.tv_usec = 0;
     FD_ZERO(&rfd);
@@ -1556,7 +1557,7 @@
 #ifdef DEBUG_FTP
 	perror("select");
 #endif
-	closesocket(ctxt->controlFd); ctxt->controlFd = -1;
+	closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
 	return(-1);
     }
     if (res == 0) {
@@ -1564,11 +1565,11 @@
 	xmlGenericError(xmlGenericErrorContext,
 		"xmlNanoFTPCloseConnection: timeout\n");
 #endif
-	closesocket(ctxt->controlFd); ctxt->controlFd = -1;
+	closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
     } else {
 	res = xmlNanoFTPGetResponse(ctxt);
 	if (res != 2) {
-	    closesocket(ctxt->controlFd); ctxt->controlFd = -1;
+	    closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
 	    return(-1);
 	}
     }
@@ -1729,7 +1730,7 @@
         if (xmlNanoFTPCwd(ctxt, ctxt->path) < 1)
 	    return(-1);
 	ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
-	if (ctxt->dataFd == -1)
+	if (ctxt->dataFd == INVALID_SOCKET)
 	    return(-1);
 	snprintf(buf, sizeof(buf), "LIST -L\r\n");
     } else {
@@ -1738,7 +1739,7 @@
 		return(-1);
 	}
 	ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
-	if (ctxt->dataFd == -1)
+	if (ctxt->dataFd == INVALID_SOCKET)
 	    return(-1);
 	snprintf(buf, sizeof(buf), "LIST -L %s\r\n", filename);
     }
@@ -1750,12 +1751,12 @@
     res = send(ctxt->controlFd, buf, len, 0);
     if (res < 0) {
 	__xmlIOErr(XML_FROM_FTP, 0, "send failed");
-	closesocket(ctxt->dataFd); ctxt->dataFd = -1;
+	closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
 	return(res);
     }
     res = xmlNanoFTPReadResponse(ctxt);
     if (res != 1) {
-	closesocket(ctxt->dataFd); ctxt->dataFd = -1;
+	closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
 	return(-res);
     }
 
@@ -1771,18 +1772,18 @@
 #ifdef DEBUG_FTP
 	    perror("select");
 #endif
-	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;
+	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
 	    return(-1);
 	}
 	if (res == 0) {
 	    res = xmlNanoFTPCheckResponse(ctxt);
 	    if (res < 0) {
-		closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-		ctxt->dataFd = -1;
+		closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+		ctxt->dataFd = INVALID_SOCKET;
 		return(-1);
 	    }
 	    if (res == 2) {
-		closesocket(ctxt->dataFd); ctxt->dataFd = -1;
+		closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
 		return(0);
 	    }
 
@@ -1791,8 +1792,8 @@
 
 	if ((len = recv(ctxt->dataFd, &buf[indx], sizeof(buf) - (indx + 1), 0)) < 0) {
 	    __xmlIOErr(XML_FROM_FTP, 0, "recv");
-	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-	    ctxt->dataFd = -1;
+	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+	    ctxt->dataFd = INVALID_SOCKET;
 	    return(-1);
 	}
 #ifdef DEBUG_FTP
@@ -1824,18 +1825,18 @@
  */
 
 
-int
+SOCKET
 xmlNanoFTPGetSocket(void *ctx, const char *filename) {
     xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
     char buf[300];
     int res, len;
     if (ctx == NULL)
-	return(-1);
+	return INVALID_SOCKET;
     if ((filename == NULL) && (ctxt->path == NULL))
-	return(-1);
+	return INVALID_SOCKET;
     ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
-    if (ctxt->dataFd == -1)
-	return(-1);
+    if (ctxt->dataFd == INVALID_SOCKET)
+	return INVALID_SOCKET;
 
     snprintf(buf, sizeof(buf), "TYPE I\r\n");
     len = strlen(buf);
@@ -1845,13 +1846,13 @@
     res = send(ctxt->controlFd, buf, len, 0);
     if (res < 0) {
 	__xmlIOErr(XML_FROM_FTP, 0, "send failed");
-	closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-	return(res);
+	closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+	return INVALID_SOCKET;
     }
     res = xmlNanoFTPReadResponse(ctxt);
     if (res != 2) {
-	closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-	return(-res);
+	closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+	return INVALID_SOCKET;
     }
     if (filename == NULL)
 	snprintf(buf, sizeof(buf), "RETR %s\r\n", ctxt->path);
@@ -1865,13 +1866,13 @@
     res = send(ctxt->controlFd, buf, len, 0);
     if (res < 0) {
 	__xmlIOErr(XML_FROM_FTP, 0, "send failed");
-	closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-	return(res);
+	closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+	return INVALID_SOCKET;
     }
     res = xmlNanoFTPReadResponse(ctxt);
     if (res != 1) {
-	closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-	return(-res);
+	closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+	return INVALID_SOCKET;
     }
     return(ctxt->dataFd);
 }
@@ -1903,7 +1904,7 @@
 	return(-1);
     if (callback == NULL)
 	return(-1);
-    if (xmlNanoFTPGetSocket(ctxt, filename) < 0)
+    if (xmlNanoFTPGetSocket(ctxt, filename) == INVALID_SOCKET)
 	return(-1);
 
     do {
@@ -1916,18 +1917,18 @@
 #ifdef DEBUG_FTP
 	    perror("select");
 #endif
-	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;
+	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
 	    return(-1);
 	}
 	if (res == 0) {
 	    res = xmlNanoFTPCheckResponse(ctxt);
 	    if (res < 0) {
-		closesocket(ctxt->dataFd); ctxt->dataFd = -1;
-		ctxt->dataFd = -1;
+		closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+		ctxt->dataFd = INVALID_SOCKET;
 		return(-1);
 	    }
 	    if (res == 2) {
-		closesocket(ctxt->dataFd); ctxt->dataFd = -1;
+		closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
 		return(0);
 	    }
 
@@ -1936,7 +1937,7 @@
 	if ((len = recv(ctxt->dataFd, buf, sizeof(buf), 0)) < 0) {
 	    __xmlIOErr(XML_FROM_FTP, 0, "recv failed");
 	    callback(userData, buf, len);
-	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;
+	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
 	    return(-1);
 	}
 	callback(userData, buf, len);
@@ -1962,7 +1963,7 @@
     xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
 
     if (ctx == NULL) return(-1);
-    if (ctxt->dataFd < 0) return(0);
+    if (ctxt->dataFd == INVALID_SOCKET) return(0);
     if (dest == NULL) return(-1);
     if (len <= 0) return(0);
 
@@ -1990,7 +1991,7 @@
 void*
 xmlNanoFTPOpen(const char *URL) {
     xmlNanoFTPCtxtPtr ctxt;
-    int sock;
+    SOCKET sock;
 
     xmlNanoFTPInit();
     if (URL == NULL) return(NULL);
@@ -2003,7 +2004,7 @@
 	return(NULL);
     }
     sock = xmlNanoFTPGetSocket(ctxt, ctxt->path);
-    if (sock < 0) {
+    if (sock == INVALID_SOCKET) {
 	xmlNanoFTPFreeCtxt(ctxt);
 	return(NULL);
     }
@@ -2026,14 +2027,14 @@
     if (ctxt == NULL)
 	return(-1);
 
-    if (ctxt->dataFd >= 0) {
+    if (ctxt->dataFd != INVALID_SOCKET) {
 	closesocket(ctxt->dataFd);
-	ctxt->dataFd = -1;
+	ctxt->dataFd = INVALID_SOCKET;
     }
-    if (ctxt->controlFd >= 0) {
+    if (ctxt->controlFd != INVALID_SOCKET) {
 	xmlNanoFTPQuit(ctxt);
 	closesocket(ctxt->controlFd);
-	ctxt->controlFd = -1;
+	ctxt->controlFd = INVALID_SOCKET;
     }
     xmlNanoFTPFreeCtxt(ctxt);
     return(0);
diff --git a/nanohttp.c b/nanohttp.c
index 9001ae5..a8af0e1 100644
--- a/nanohttp.c
+++ b/nanohttp.c
@@ -54,9 +54,13 @@
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif
+#ifndef HAVE_POLL_H
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
 #endif
+#else
+#include <poll.h>
+#endif
 #ifdef HAVE_STRINGS_H
 #include <strings.h>
 #endif
@@ -71,18 +75,18 @@
 #ifdef VMS
 #include <stropts>
 #define XML_SOCKLEN_T unsigned int
-#define SOCKET int
 #endif
 
 #if defined(__MINGW32__) || defined(_WIN32_WCE)
+#ifndef _WINSOCKAPI_
 #define _WINSOCKAPI_
+#endif
 #include <wsockcompat.h>
 #include <winsock2.h>
 #undef XML_SOCKLEN_T
 #define XML_SOCKLEN_T unsigned int
 #endif
 
-
 #include <libxml/globals.h>
 #include <libxml/xmlerror.h>
 #include <libxml/xmlmemory.h>
@@ -99,6 +103,7 @@
 #define closesocket(s) close(s)
 #endif
 #define SOCKET int
+#define INVALID_SOCKET (-1)
 #endif
 
 #ifdef __BEOS__
@@ -110,9 +115,6 @@
 #ifndef XML_SOCKLEN_T
 #define XML_SOCKLEN_T unsigned int
 #endif
-#ifndef SOCKET
-#define SOCKET int
-#endif
 
 #ifdef STANDALONE
 #define DEBUG_HTTP
@@ -146,6 +148,7 @@
     int inlen;		/* len of the input buffer */
     int last;		/* return code for last operation */
     int returnValue;	/* the protocol return value */
+    int version;        /* the protocol version */
     int ContentLength;  /* specified content length from HTTP header */
     char *contentType;	/* the MIME type for the input */
     char *location;	/* the new URL in case of redirect */
@@ -191,10 +194,10 @@
 #ifdef SUPPORT_IP6
 static
 int have_ipv6(void) {
-    int s;
+    SOCKET s;
 
     s = socket (AF_INET6, SOCK_STREAM, 0);
-    if (s != -1) {
+    if (s != INVALID_SOCKET) {
 	close (s);
 	return (1);
     }
@@ -388,7 +391,7 @@
     memset(ret, 0, sizeof(xmlNanoHTTPCtxt));
     ret->port = 80;
     ret->returnValue = 0;
-    ret->fd = -1;
+    ret->fd = INVALID_SOCKET;
     ret->ContentLength = -1;
 
     xmlNanoHTTPScanURL(ret, URL);
@@ -425,8 +428,8 @@
 #endif
 
     ctxt->state = XML_NANO_HTTP_NONE;
-    if (ctxt->fd >= 0) closesocket(ctxt->fd);
-    ctxt->fd = -1;
+    if (ctxt->fd != INVALID_SOCKET) closesocket(ctxt->fd);
+    ctxt->fd = INVALID_SOCKET;
     xmlFree(ctxt);
 }
 
@@ -439,51 +442,64 @@
  */
 
 static int
-xmlNanoHTTPSend(xmlNanoHTTPCtxtPtr ctxt, const char * xmt_ptr, int outlen) {
+xmlNanoHTTPSend(xmlNanoHTTPCtxtPtr ctxt, const char *xmt_ptr, int outlen)
+{
+    int total_sent = 0;
+#ifdef HAVE_POLL_H
+    struct pollfd p;
+#else
+    struct timeval tv;
+    fd_set wfd;
+#endif
 
-    int 	total_sent = 0;
-
-    if ( (ctxt->state & XML_NANO_HTTP_WRITE) && (xmt_ptr != NULL ) ) {
+    if ((ctxt->state & XML_NANO_HTTP_WRITE) && (xmt_ptr != NULL)) {
         while (total_sent < outlen) {
             int nsent = send(ctxt->fd, xmt_ptr + total_sent,
-                                      outlen - total_sent, 0);
-            if (nsent>0)
+                             outlen - total_sent, 0);
+
+            if (nsent > 0)
                 total_sent += nsent;
-	    else if ( ( nsent == -1 ) && 
+            else if ((nsent == -1) &&
 #if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
-	    	      ( socket_errno( ) != EAGAIN ) &&
+                     (socket_errno() != EAGAIN) &&
 #endif
-		        ( socket_errno( ) != EWOULDBLOCK ) ) {
-		__xmlIOErr(XML_FROM_HTTP, 0, "send failed\n");
-		if ( total_sent == 0 )
-		    total_sent = -1;
-		break;
-	    }
-	    else {
-	        /*
-		**  No data sent
-		**  Since non-blocking sockets are used, wait for 
-		**  socket to be writable or default timeout prior
-		**  to retrying.
-		*/
+                     (socket_errno() != EWOULDBLOCK)) {
+                __xmlIOErr(XML_FROM_HTTP, 0, "send failed\n");
+                if (total_sent == 0)
+                    total_sent = -1;
+                break;
+            } else {
+                /*
+                 * No data sent
+                 * Since non-blocking sockets are used, wait for
+                 * socket to be writable or default timeout prior
+                 * to retrying.
+                 */
+#ifndef HAVE_POLL_H
+#ifndef _WINSOCKAPI_
+                if (ctxt->fd > FD_SETSIZE)
+                    return -1;
+#endif
 
-		struct timeval	tv;
-		fd_set		wfd;
-
-		tv.tv_sec = timeout;
-		tv.tv_usec = 0;
-		FD_ZERO( &wfd );
+                tv.tv_sec = timeout;
+                tv.tv_usec = 0;
+                FD_ZERO(&wfd);
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable: 4018)
 #endif
-		FD_SET( ctxt->fd, &wfd );
+                FD_SET(ctxt->fd, &wfd);
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
-		(void)select( ctxt->fd + 1, NULL, &wfd, NULL, &tv );
-	    }
-	}
+                (void) select(ctxt->fd + 1, NULL, &wfd, NULL, &tv);
+#else
+                p.fd = ctxt->fd;
+                p.events = POLLOUT;
+                (void) poll(&p, 1, timeout * 1000);
+#endif /* !HAVE_POLL_H */
+            }
+        }
     }
 
     return total_sent;
@@ -500,96 +516,119 @@
  */
 
 static int
-xmlNanoHTTPRecv(xmlNanoHTTPCtxtPtr ctxt) {
+xmlNanoHTTPRecv(xmlNanoHTTPCtxtPtr ctxt)
+{
+#ifdef HAVE_POLL_H
+    struct pollfd p;
+#else
     fd_set rfd;
     struct timeval tv;
+#endif
 
 
     while (ctxt->state & XML_NANO_HTTP_READ) {
-	if (ctxt->in == NULL) {
-	    ctxt->in = (char *) xmlMallocAtomic(65000 * sizeof(char));
-	    if (ctxt->in == NULL) {
-		xmlHTTPErrMemory("allocating input");
-	        ctxt->last = -1;
-		return(-1);
-	    }
-	    ctxt->inlen = 65000;
-	    ctxt->inptr = ctxt->content = ctxt->inrptr = ctxt->in;
-	}
-	if (ctxt->inrptr > ctxt->in + XML_NANO_HTTP_CHUNK) {
-	    int delta = ctxt->inrptr - ctxt->in;
-	    int len = ctxt->inptr - ctxt->inrptr;
-	    
-	    memmove(ctxt->in, ctxt->inrptr, len);
-	    ctxt->inrptr -= delta;
-	    ctxt->content -= delta;
-	    ctxt->inptr -= delta;
-	}
-        if ((ctxt->in + ctxt->inlen) < (ctxt->inptr + XML_NANO_HTTP_CHUNK)) {
-	    int d_inptr = ctxt->inptr - ctxt->in;
-	    int d_content = ctxt->content - ctxt->in;
-	    int d_inrptr = ctxt->inrptr - ctxt->in;
-	    char *	tmp_ptr = ctxt->in;
+        if (ctxt->in == NULL) {
+            ctxt->in = (char *) xmlMallocAtomic(65000 * sizeof(char));
+            if (ctxt->in == NULL) {
+                xmlHTTPErrMemory("allocating input");
+                ctxt->last = -1;
+                return (-1);
+            }
+            ctxt->inlen = 65000;
+            ctxt->inptr = ctxt->content = ctxt->inrptr = ctxt->in;
+        }
+        if (ctxt->inrptr > ctxt->in + XML_NANO_HTTP_CHUNK) {
+            int delta = ctxt->inrptr - ctxt->in;
+            int len = ctxt->inptr - ctxt->inrptr;
 
-	    ctxt->inlen *= 2;
+            memmove(ctxt->in, ctxt->inrptr, len);
+            ctxt->inrptr -= delta;
+            ctxt->content -= delta;
+            ctxt->inptr -= delta;
+        }
+        if ((ctxt->in + ctxt->inlen) < (ctxt->inptr + XML_NANO_HTTP_CHUNK)) {
+            int d_inptr = ctxt->inptr - ctxt->in;
+            int d_content = ctxt->content - ctxt->in;
+            int d_inrptr = ctxt->inrptr - ctxt->in;
+            char *tmp_ptr = ctxt->in;
+
+            ctxt->inlen *= 2;
             ctxt->in = (char *) xmlRealloc(tmp_ptr, ctxt->inlen);
-	    if (ctxt->in == NULL) {
-		xmlHTTPErrMemory("allocating input buffer");
-		xmlFree( tmp_ptr );
-	        ctxt->last = -1;
-		return(-1);
-	    }
+            if (ctxt->in == NULL) {
+                xmlHTTPErrMemory("allocating input buffer");
+                xmlFree(tmp_ptr);
+                ctxt->last = -1;
+                return (-1);
+            }
             ctxt->inptr = ctxt->in + d_inptr;
             ctxt->content = ctxt->in + d_content;
             ctxt->inrptr = ctxt->in + d_inrptr;
-	}
-	ctxt->last = recv(ctxt->fd, ctxt->inptr, XML_NANO_HTTP_CHUNK, 0);
-	if (ctxt->last > 0) {
-	    ctxt->inptr += ctxt->last;
-	    return(ctxt->last);
-	}
-	if (ctxt->last == 0) {
-	    return(0);
-	}
-	if (ctxt->last == -1) {
-	    switch (socket_errno()) {
-		case EINPROGRESS:
-		case EWOULDBLOCK:
+        }
+        ctxt->last = recv(ctxt->fd, ctxt->inptr, XML_NANO_HTTP_CHUNK, 0);
+        if (ctxt->last > 0) {
+            ctxt->inptr += ctxt->last;
+            return (ctxt->last);
+        }
+        if (ctxt->last == 0) {
+            return (0);
+        }
+        if (ctxt->last == -1) {
+            switch (socket_errno()) {
+                case EINPROGRESS:
+                case EWOULDBLOCK:
 #if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
-		case EAGAIN:
+                case EAGAIN:
 #endif
-		    break;
+                    break;
 
-		case ECONNRESET:
-		case ESHUTDOWN:
-		    return ( 0 );
+                case ECONNRESET:
+                case ESHUTDOWN:
+                    return (0);
 
-		default:
-		    __xmlIOErr(XML_FROM_HTTP, 0, "recv failed\n");
-		    return(-1);
-	    }
-	}
+                default:
+                    __xmlIOErr(XML_FROM_HTTP, 0, "recv failed\n");
+                    return (-1);
+            }
+        }
+#ifdef HAVE_POLL_H
+        p.fd = ctxt->fd;
+        p.events = POLLIN;
+        if ((poll(&p, 1, timeout * 1000) < 1)
+#if defined(EINTR)
+            && (errno != EINTR)
+#endif
+            )
+            return (0);
+#else /* !HAVE_POLL_H */
+#ifndef _WINSOCKAPI_
+        if (ctxt->fd > FD_SETSIZE)
+            return 0;
+#endif
 
-	tv.tv_sec = timeout;
-	tv.tv_usec = 0;
-	FD_ZERO(&rfd);
+        tv.tv_sec = timeout;
+        tv.tv_usec = 0;
+        FD_ZERO(&rfd);
+
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable: 4018)
 #endif
-	FD_SET(ctxt->fd, &rfd);
+
+        FD_SET(ctxt->fd, &rfd);
+
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
-	
-	if ( (select(ctxt->fd+1, &rfd, NULL, NULL, &tv)<1)
+
+        if ((select(ctxt->fd + 1, &rfd, NULL, NULL, &tv) < 1)
 #if defined(EINTR)
-		&& (errno != EINTR)
+            && (errno != EINTR)
 #endif
-	)
-		return(0);
+            )
+            return (0);
+#endif /* !HAVE_POLL_H */
     }
-    return(0);
+    return (0);
 }
 
 /**
@@ -686,6 +725,7 @@
 	}
 	if ((*cur != 0) && (*cur != ' ') && (*cur != '\t')) return;
 	ctxt->returnValue = ret;
+        ctxt->version = version;
     } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Content-Type:", 13)) {
         const xmlChar *charset, *last, *mime;
         cur += 13;
@@ -800,90 +840,99 @@
  * Returns -1 in case of failure, the file descriptor number otherwise
  */
 
-static int
+static SOCKET
 xmlNanoHTTPConnectAttempt(struct sockaddr *addr)
 {
+#ifndef HAVE_POLL_H
     fd_set wfd;
 #ifdef _WINSOCKAPI_
     fd_set xfd;
 #endif
     struct timeval tv;
+#else /* !HAVE_POLL_H */
+    struct pollfd p;
+#endif /* !HAVE_POLL_H */
     int status;
+
     int addrlen;
+
     SOCKET s;
-    
+
 #ifdef SUPPORT_IP6
     if (addr->sa_family == AF_INET6) {
-	s = socket (PF_INET6, SOCK_STREAM, IPPROTO_TCP);
-	addrlen = sizeof (struct sockaddr_in6);
-    }
-    else
+        s = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
+        addrlen = sizeof(struct sockaddr_in6);
+    } else
 #endif
     {
-	s = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
-	addrlen = sizeof (struct sockaddr_in);
+        s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+        addrlen = sizeof(struct sockaddr_in);
     }
-    if (s==-1) {
+    if (s == INVALID_SOCKET) {
 #ifdef DEBUG_HTTP
-	perror("socket");
+        perror("socket");
 #endif
-	__xmlIOErr(XML_FROM_HTTP, 0, "socket failed\n");
-	return(-1);
+        __xmlIOErr(XML_FROM_HTTP, 0, "socket failed\n");
+        return INVALID_SOCKET;
     }
-    
 #ifdef _WINSOCKAPI_
     {
-	u_long one = 1;
+        u_long one = 1;
 
-	status = ioctlsocket(s, FIONBIO, &one) == SOCKET_ERROR ? -1 : 0;
+        status = ioctlsocket(s, FIONBIO, &one) == SOCKET_ERROR ? -1 : 0;
     }
 #else /* _WINSOCKAPI_ */
 #if defined(VMS)
     {
-	int enable = 1;
-	status = ioctl(s, FIONBIO, &enable);
+        int enable = 1;
+
+        status = ioctl(s, FIONBIO, &enable);
     }
 #else /* VMS */
 #if defined(__BEOS__) && !defined(__HAIKU__)
-	{
-		bool noblock = true;
-		status = setsockopt(s, SOL_SOCKET, SO_NONBLOCK, &noblock, sizeof(noblock));
-	}
+    {
+        bool noblock = true;
+
+        status =
+            setsockopt(s, SOL_SOCKET, SO_NONBLOCK, &noblock,
+                       sizeof(noblock));
+    }
 #else /* __BEOS__ */
     if ((status = fcntl(s, F_GETFL, 0)) != -1) {
 #ifdef O_NONBLOCK
-	status |= O_NONBLOCK;
+        status |= O_NONBLOCK;
 #else /* O_NONBLOCK */
 #ifdef F_NDELAY
-	status |= F_NDELAY;
+        status |= F_NDELAY;
 #endif /* F_NDELAY */
 #endif /* !O_NONBLOCK */
-	status = fcntl(s, F_SETFL, status);
+        status = fcntl(s, F_SETFL, status);
     }
     if (status < 0) {
 #ifdef DEBUG_HTTP
-	perror("nonblocking");
+        perror("nonblocking");
 #endif
-	__xmlIOErr(XML_FROM_HTTP, 0, "error setting non-blocking IO\n");
-	closesocket(s);
-	return(-1);
+        __xmlIOErr(XML_FROM_HTTP, 0, "error setting non-blocking IO\n");
+        closesocket(s);
+        return INVALID_SOCKET;
     }
 #endif /* !__BEOS__ */
 #endif /* !VMS */
 #endif /* !_WINSOCKAPI_ */
 
-    if (connect (s, addr, addrlen) == -1) {
-	switch (socket_errno()) {
-	    case EINPROGRESS:
-	    case EWOULDBLOCK:
-		break;
-	    default:
-		__xmlIOErr(XML_FROM_HTTP, 0, "error connecting to HTTP server");
-		closesocket(s);
-		return(-1);
-	}
-    }	
-    
+    if (connect(s, addr, addrlen) == -1) {
+        switch (socket_errno()) {
+            case EINPROGRESS:
+            case EWOULDBLOCK:
+                break;
+            default:
+                __xmlIOErr(XML_FROM_HTTP, 0,
+                           "error connecting to HTTP server");
+                closesocket(s);
+                return INVALID_SOCKET;
+        }
+    }
+#ifndef HAVE_POLL_H
     tv.tv_sec = timeout;
     tv.tv_usec = 0;
 
@@ -891,63 +940,82 @@
 #pragma warning(push)
 #pragma warning(disable: 4018)
 #endif
+#ifndef _WINSOCKAPI_
+    if (s > FD_SETSIZE)
+        return INVALID_SOCKET;
+#endif
     FD_ZERO(&wfd);
     FD_SET(s, &wfd);
 
-#ifdef _WINSOCKAPI_    
+#ifdef _WINSOCKAPI_
     FD_ZERO(&xfd);
     FD_SET(s, &xfd);
-    
-    switch(select(s+1, NULL, &wfd, &xfd, &tv))
+
+    switch (select(s + 1, NULL, &wfd, &xfd, &tv))
 #else
-    switch(select(s+1, NULL, &wfd, NULL, &tv))
+    switch (select(s + 1, NULL, &wfd, NULL, &tv))
 #endif
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
+
+#else /* !HAVE_POLL_H */
+    p.fd = s;
+    p.events = POLLOUT;
+    switch (poll(&p, 1, timeout * 1000))
+#endif /* !HAVE_POLL_H */
+
     {
-	case 0:
-	    /* Time out */
-	    __xmlIOErr(XML_FROM_HTTP, 0, "Connect attempt timed out");
-	    closesocket(s);
-	    return(-1);
-	case -1:
-	    /* Ermm.. ?? */
-	    __xmlIOErr(XML_FROM_HTTP, 0, "Connect failed");
-	    closesocket(s);
-	    return(-1);
+        case 0:
+            /* Time out */
+            __xmlIOErr(XML_FROM_HTTP, 0, "Connect attempt timed out");
+            closesocket(s);
+            return INVALID_SOCKET;
+        case -1:
+            /* Ermm.. ?? */
+            __xmlIOErr(XML_FROM_HTTP, 0, "Connect failed");
+            closesocket(s);
+            return INVALID_SOCKET;
     }
 
-    if ( FD_ISSET(s, &wfd)
+#ifndef HAVE_POLL_H
+    if (FD_ISSET(s, &wfd)
 #ifdef _WINSOCKAPI_
-                           || FD_ISSET(s, &xfd)
+        || FD_ISSET(s, &xfd)
 #endif
-                                                ) {
-	XML_SOCKLEN_T len;
-	len = sizeof(status);
+        )
+#else /* !HAVE_POLL_H */
+    if (p.revents == POLLOUT)
+#endif /* !HAVE_POLL_H */
+    {
+        XML_SOCKLEN_T len;
+
+        len = sizeof(status);
 #ifdef SO_ERROR
-	if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*)&status, &len) < 0 ) {
-	    /* Solaris error code */
-	    __xmlIOErr(XML_FROM_HTTP, 0, "getsockopt failed\n");
-	    return (-1);
-	}
+        if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char *) &status, &len) <
+            0) {
+            /* Solaris error code */
+            __xmlIOErr(XML_FROM_HTTP, 0, "getsockopt failed\n");
+            return INVALID_SOCKET;
+        }
 #endif
-	if ( status ) {
-	    __xmlIOErr(XML_FROM_HTTP, 0, "Error connecting to remote host");
-	    closesocket(s);
-	    errno = status;
-	    return (-1);
-	}
+        if (status) {
+            __xmlIOErr(XML_FROM_HTTP, 0,
+                       "Error connecting to remote host");
+            closesocket(s);
+            errno = status;
+            return INVALID_SOCKET;
+        }
     } else {
-	/* pbm */
-	__xmlIOErr(XML_FROM_HTTP, 0, "select failed\n");
-	closesocket(s);
-	return (-1);
+        /* pbm */
+        __xmlIOErr(XML_FROM_HTTP, 0, "select failed\n");
+        closesocket(s);
+        return INVALID_SOCKET;
     }
-    
-    return(s);
+
+    return (s);
 }
- 
+
 /**
  * xmlNanoHTTPConnectHost:
  * @host:  the host name
@@ -959,7 +1027,7 @@
  * Returns -1 in case of failure, the file descriptor number otherwise
  */
 
-static int
+static SOCKET
 xmlNanoHTTPConnectHost(const char *host, int port)
 {
     struct hostent *h;
@@ -972,7 +1040,7 @@
     struct sockaddr_in6 sockin6;
 #endif
     int i;
-    int s;
+    SOCKET s;
 
     memset (&sockin, 0, sizeof(sockin));
 #ifdef SUPPORT_IP6
@@ -1003,7 +1071,7 @@
 	status = getaddrinfo (host, NULL, &hints, &result);
 	if (status) {
 	    __xmlIOErr(XML_FROM_HTTP, 0, "getaddrinfo failed\n");
-	    return (-1);
+	    return INVALID_SOCKET;
 	}
 
 	for (res = result; res; res = res->ai_next) {
@@ -1011,7 +1079,7 @@
 		if (res->ai_addrlen > sizeof(sockin)) {
 		    __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
 		    freeaddrinfo (result);
-		    return (-1);
+		    return INVALID_SOCKET;
 		}
 		memcpy (&sockin, res->ai_addr, res->ai_addrlen);
 		sockin.sin_port = htons (port);
@@ -1021,7 +1089,7 @@
 		if (res->ai_addrlen > sizeof(sockin6)) {
 		    __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
 		    freeaddrinfo (result);
-		    return (-1);
+		    return INVALID_SOCKET;
 		}
 		memcpy (&sockin6, res->ai_addr, res->ai_addrlen);
 		sockin6.sin6_port = htons (port);
@@ -1031,7 +1099,7 @@
 		continue;              /* for */
 
 	    s = xmlNanoHTTPConnectAttempt (addr);
-	    if (s != -1) {
+	    if (s != INVALID_SOCKET) {
 		freeaddrinfo (result);
 		return (s);
 	    }
@@ -1085,7 +1153,7 @@
 #else
 	    __xmlIOErr(XML_FROM_HTTP, 0, "Failed to resolve host");
 #endif
-	    return (-1);
+	    return INVALID_SOCKET;
 	}
 
 	for (i = 0; h->h_addr_list[i]; i++) {
@@ -1093,7 +1161,7 @@
 		/* A records (IPv4) */
 		if ((unsigned int) h->h_length > sizeof(ia)) {
 		    __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
-		    return (-1);
+		    return INVALID_SOCKET;
 		}
 		memcpy (&ia, h->h_addr_list[i], h->h_length);
 		sockin.sin_family = h->h_addrtype;
@@ -1105,7 +1173,7 @@
 		/* AAAA records (IPv6) */
 		if ((unsigned int) h->h_length > sizeof(ia6)) {
 		    __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
-		    return (-1);
+		    return INVALID_SOCKET;
 		}
 		memcpy (&ia6, h->h_addr_list[i], h->h_length);
 		sockin6.sin6_family = h->h_addrtype;
@@ -1117,7 +1185,7 @@
 		break;              /* for */
 
 	    s = xmlNanoHTTPConnectAttempt (addr);
-	    if (s != -1)
+	    if (s != INVALID_SOCKET)
 		return (s);
 	}
     }
@@ -1128,7 +1196,7 @@
                     "xmlNanoHTTPConnectHost:  unable to connect to '%s'.\n",
                     host);
 #endif
-    return (-1);
+    return INVALID_SOCKET;
 }
 
 
@@ -1272,8 +1340,8 @@
 		  const char *headers, int ilen ) {
     xmlNanoHTTPCtxtPtr ctxt;
     char *bp, *p;
-    int blen, ret;
-    int head;
+    int blen;
+    SOCKET ret;
     int nbRedirects = 0;
     char *redirURL = NULL;
 #ifdef DEBUG_HTTP
@@ -1317,7 +1385,7 @@
 	blen = strlen(ctxt->hostname);
 	ret = xmlNanoHTTPConnectHost(ctxt->hostname, ctxt->port);
     }
-    if (ret < 0) {
+    if (ret == INVALID_SOCKET) {
         xmlNanoHTTPFreeCtxt(ctxt);
 	if (redirURL != NULL) xmlFree(redirURL);
         return(NULL);
@@ -1435,11 +1503,9 @@
     }
 
     ctxt->state = XML_NANO_HTTP_READ;
-    head = 1;
 
     while ((p = xmlNanoHTTPReadLine(ctxt)) != NULL) {
-        if (head && (*p == 0)) {
-	    head = 0;
+        if (*p == 0) {
 	    ctxt->content = ctxt->inrptr;
 	    xmlFree(p);
 	    break;
@@ -1549,7 +1615,8 @@
     char *buf = NULL;
     int fd;
     int len;
-    
+    int ret = 0;
+
     if (filename == NULL) return(-1);
     ctxt = xmlNanoHTTPOpen(URL, contentType);
     if (ctxt == NULL) return(-1);
@@ -1570,12 +1637,14 @@
 
     xmlNanoHTTPFetchContent( ctxt, &buf, &len );
     if ( len > 0 ) {
-	write(fd, buf, len);
+	if (write(fd, buf, len) == -1) {
+	    ret = -1;
+	}
     }
 
     xmlNanoHTTPClose(ctxt);
     close(fd);
-    return(0);
+    return(ret);
 }
 
 #ifdef LIBXML_OUTPUT_ENABLED
@@ -1594,7 +1663,8 @@
     char *buf = NULL;
     int fd;
     int len;
-    
+    int ret = 0;
+
     if ((ctxt == NULL) || (filename == NULL)) return(-1);
 
     if (!strcmp(filename, "-")) 
@@ -1609,12 +1679,14 @@
 
     xmlNanoHTTPFetchContent( ctxt, &buf, &len );
     if ( len > 0 ) {
-	write(fd, buf, len);
+	if (write(fd, buf, len) == -1) {
+	    ret = -1;
+	}
     }
 
     xmlNanoHTTPClose(ctxt);
     close(fd);
-    return(0);
+    return(ret);
 }
 #endif /* LIBXML_OUTPUT_ENABLED */
 
diff --git a/parser.c b/parser.c
index 6de2ef4..72a467c 100644
--- a/parser.c
+++ b/parser.c
@@ -79,10 +79,17 @@
 #ifdef HAVE_ZLIB_H
 #include <zlib.h>
 #endif
+#ifdef HAVE_LZMA_H
+#include <lzma.h>
+#endif
 
 static void
 xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info);
 
+static xmlParserCtxtPtr
+xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
+	                  const xmlChar *base, xmlParserCtxtPtr pctx);
+
 /************************************************************************
  *									*
  *	Arbitrary limits set in the parser. See XML_PARSE_HUGE		*
@@ -193,13 +200,14 @@
 
 static const char *xmlW3CPIs[] = {
     "xml-stylesheet",
+    "xml-model",
     NULL
 };
 
 
 /* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
-xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
-                                       const xmlChar **str);
+static xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
+                                              const xmlChar **str);
 
 static xmlParserErrors
 xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
@@ -246,14 +254,15 @@
 	return;
     if (ctxt != NULL)
 	ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
+
     if (prefix == NULL)
         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
-                        ctxt->errNo, XML_ERR_FATAL, NULL, 0,
+                        XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
                         (const char *) localname, NULL, NULL, 0, 0,
                         "Attribute %s redefined\n", localname);
     else
         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
-                        ctxt->errNo, XML_ERR_FATAL, NULL, 0,
+                        XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
                         (const char *) prefix, (const char *) localname,
                         NULL, 0, 0, "Attribute %s:%s redefined\n", prefix,
                         localname);
@@ -519,13 +528,21 @@
     if ((ctxt != NULL) && (ctxt->sax != NULL) &&
         (ctxt->sax->initialized == XML_SAX2_MAGIC))
         schannel = ctxt->sax->serror;
-    __xmlRaiseError(schannel,
+    if (ctxt != NULL) {
+        __xmlRaiseError(schannel,
                     (ctxt->sax) ? ctxt->sax->warning : NULL,
                     ctxt->userData,
                     ctxt, NULL, XML_FROM_PARSER, error,
                     XML_ERR_WARNING, NULL, 0,
 		    (const char *) str1, (const char *) str2, NULL, 0, 0,
 		    msg, (const char *) str1, (const char *) str2);
+    } else {
+        __xmlRaiseError(schannel, NULL, NULL,
+                    ctxt, NULL, XML_FROM_PARSER, error,
+                    XML_ERR_WARNING, NULL, 0,
+		    (const char *) str1, (const char *) str2, NULL, 0, 0,
+		    msg, (const char *) str1, (const char *) str2);
+    }
 }
 
 /**
@@ -551,14 +568,20 @@
 	if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
 	    schannel = ctxt->sax->serror;
     }
-    __xmlRaiseError(schannel,
+    if (ctxt != NULL) {
+        __xmlRaiseError(schannel,
                     ctxt->vctxt.error, ctxt->vctxt.userData,
                     ctxt, NULL, XML_FROM_DTD, error,
                     XML_ERR_ERROR, NULL, 0, (const char *) str1,
 		    (const char *) str2, NULL, 0, 0,
 		    msg, (const char *) str1, (const char *) str2);
-    if (ctxt != NULL) {
 	ctxt->valid = 0;
+    } else {
+        __xmlRaiseError(schannel, NULL, NULL,
+                    ctxt, NULL, XML_FROM_DTD, error,
+                    XML_ERR_ERROR, NULL, 0, (const char *) str1,
+		    (const char *) str2, NULL, 0, 0,
+		    msg, (const char *) str1, (const char *) str2);
     }
 }
 
@@ -723,8 +746,6 @@
     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
         (ctxt->instate == XML_PARSER_EOF))
 	return;
-    if (ctxt != NULL)
-	ctxt->errNo = error;
     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
                     XML_ERR_WARNING, NULL, 0, (const char *) info1,
                     (const char *) info2, (const char *) info3, 0, 0, msg,
@@ -937,6 +958,12 @@
 #else
             return(0);
 #endif
+        case XML_WITH_LZMA:
+#ifdef LIBXML_LZMA_ENABLED
+            return(1);
+#else
+            return(0);
+#endif
         case XML_WITH_ICU:
 #ifdef LIBXML_ICU_ENABLED
             return(1);
@@ -1286,60 +1313,182 @@
  * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
  * [38] Subcode ::= ([a-z] | [A-Z])+
  *
+ * The current REC reference the sucessors of RFC 1766, currently 5646
+ *
+ * http://www.rfc-editor.org/rfc/rfc5646.txt
+ * langtag       = language
+ *                 ["-" script]
+ *                 ["-" region]
+ *                 *("-" variant)
+ *                 *("-" extension)
+ *                 ["-" privateuse]
+ * language      = 2*3ALPHA            ; shortest ISO 639 code
+ *                 ["-" extlang]       ; sometimes followed by
+ *                                     ; extended language subtags
+ *               / 4ALPHA              ; or reserved for future use
+ *               / 5*8ALPHA            ; or registered language subtag
+ *
+ * extlang       = 3ALPHA              ; selected ISO 639 codes
+ *                 *2("-" 3ALPHA)      ; permanently reserved
+ *
+ * script        = 4ALPHA              ; ISO 15924 code
+ *
+ * region        = 2ALPHA              ; ISO 3166-1 code
+ *               / 3DIGIT              ; UN M.49 code
+ *
+ * variant       = 5*8alphanum         ; registered variants
+ *               / (DIGIT 3alphanum)
+ *
+ * extension     = singleton 1*("-" (2*8alphanum))
+ *
+ *                                     ; Single alphanumerics
+ *                                     ; "x" reserved for private use
+ * singleton     = DIGIT               ; 0 - 9
+ *               / %x41-57             ; A - W
+ *               / %x59-5A             ; Y - Z
+ *               / %x61-77             ; a - w
+ *               / %x79-7A             ; y - z
+ *
+ * it sounds right to still allow Irregular i-xxx IANA and user codes too
+ * The parser below doesn't try to cope with extension or privateuse
+ * that could be added but that's not interoperable anyway
+ *
  * Returns 1 if correct 0 otherwise
  **/
 int
 xmlCheckLanguageID(const xmlChar * lang)
 {
-    const xmlChar *cur = lang;
+    const xmlChar *cur = lang, *nxt;
 
     if (cur == NULL)
         return (0);
     if (((cur[0] == 'i') && (cur[1] == '-')) ||
-        ((cur[0] == 'I') && (cur[1] == '-'))) {
+        ((cur[0] == 'I') && (cur[1] == '-')) ||
+        ((cur[0] == 'x') && (cur[1] == '-')) ||
+        ((cur[0] == 'X') && (cur[1] == '-'))) {
         /*
-         * IANA code
+         * Still allow IANA code and user code which were coming
+         * from the previous version of the XML-1.0 specification
+         * it's deprecated but we should not fail
          */
         cur += 2;
-        while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||  /* non input consuming */
+        while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
                ((cur[0] >= 'a') && (cur[0] <= 'z')))
             cur++;
-    } else if (((cur[0] == 'x') && (cur[1] == '-')) ||
-               ((cur[0] == 'X') && (cur[1] == '-'))) {
-        /*
-         * User code
-         */
-        cur += 2;
-        while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||  /* non input consuming */
-               ((cur[0] >= 'a') && (cur[0] <= 'z')))
-            cur++;
-    } else if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
-               ((cur[0] >= 'a') && (cur[0] <= 'z'))) {
-        /*
-         * ISO639
-         */
-        cur++;
-        if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
-            ((cur[0] >= 'a') && (cur[0] <= 'z')))
-            cur++;
-        else
-            return (0);
-    } else
-        return (0);
-    while (cur[0] != 0) {       /* non input consuming */
-        if (cur[0] != '-')
-            return (0);
-        cur++;
-        if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
-            ((cur[0] >= 'a') && (cur[0] <= 'z')))
-            cur++;
-        else
-            return (0);
-        while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||  /* non input consuming */
-               ((cur[0] >= 'a') && (cur[0] <= 'z')))
-            cur++;
+        return(cur[0] == 0);
     }
+    nxt = cur;
+    while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
+           ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
+           nxt++;
+    if (nxt - cur >= 4) {
+        /*
+         * Reserved
+         */
+        if ((nxt - cur > 8) || (nxt[0] != 0))
+            return(0);
+        return(1);
+    }
+    if (nxt - cur < 2)
+        return(0);
+    /* we got an ISO 639 code */
+    if (nxt[0] == 0)
+        return(1);
+    if (nxt[0] != '-')
+        return(0);
+
+    nxt++;
+    cur = nxt;
+    /* now we can have extlang or script or region or variant */
+    if ((nxt[0] >= '0') && (nxt[0] <= '9'))
+        goto region_m49;
+
+    while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
+           ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
+           nxt++;
+    if (nxt - cur == 4)
+        goto script;
+    if (nxt - cur == 2)
+        goto region;
+    if ((nxt - cur >= 5) && (nxt - cur <= 8))
+        goto variant;
+    if (nxt - cur != 3)
+        return(0);
+    /* we parsed an extlang */
+    if (nxt[0] == 0)
+        return(1);
+    if (nxt[0] != '-')
+        return(0);
+
+    nxt++;
+    cur = nxt;
+    /* now we can have script or region or variant */
+    if ((nxt[0] >= '0') && (nxt[0] <= '9'))
+        goto region_m49;
+
+    while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
+           ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
+           nxt++;
+    if (nxt - cur == 2)
+        goto region;
+    if ((nxt - cur >= 5) && (nxt - cur <= 8))
+        goto variant;
+    if (nxt - cur != 4)
+        return(0);
+    /* we parsed a script */
+script:
+    if (nxt[0] == 0)
+        return(1);
+    if (nxt[0] != '-')
+        return(0);
+
+    nxt++;
+    cur = nxt;
+    /* now we can have region or variant */
+    if ((nxt[0] >= '0') && (nxt[0] <= '9'))
+        goto region_m49;
+
+    while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
+           ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
+           nxt++;
+
+    if ((nxt - cur >= 5) && (nxt - cur <= 8))
+        goto variant;
+    if (nxt - cur != 2)
+        return(0);
+    /* we parsed a region */
+region:
+    if (nxt[0] == 0)
+        return(1);
+    if (nxt[0] != '-')
+        return(0);
+
+    nxt++;
+    cur = nxt;
+    /* now we can just have a variant */
+    while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
+           ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
+           nxt++;
+
+    if ((nxt - cur < 5) || (nxt - cur > 8))
+        return(0);
+
+    /* we parsed a variant */
+variant:
+    if (nxt[0] == 0)
+        return(1);
+    if (nxt[0] != '-')
+        return(0);
+    /* extensions and private use subtags not checked */
     return (1);
+
+region_m49:
+    if (((nxt[1] >= '0') && (nxt[1] <= '9')) &&
+        ((nxt[2] >= '0') && (nxt[2] <= '9'))) {
+        nxt += 3;
+        goto region;
+    }
+    return(0);
 }
 
 /************************************************************************
@@ -1348,8 +1497,8 @@
  *									*
  ************************************************************************/
 
-xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
-                                     const xmlChar ** str);
+static xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
+                                            const xmlChar ** str);
 
 #ifdef SAX2
 /**
@@ -1680,15 +1829,14 @@
 
     if (ctxt->nameNr >= ctxt->nameMax) {
         const xmlChar * *tmp;
-        ctxt->nameMax *= 2;
         tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
-                                    ctxt->nameMax *
+                                    ctxt->nameMax * 2 *
                                     sizeof(ctxt->nameTab[0]));
         if (tmp == NULL) {
-	    ctxt->nameMax /= 2;
 	    goto mem_error;
         }
 	ctxt->nameTab = tmp;
+        ctxt->nameMax *= 2;
     }
     ctxt->nameTab[ctxt->nameNr] = value;
     ctxt->name = value;
@@ -1853,7 +2001,7 @@
 
 static void xmlGROW (xmlParserCtxtPtr ctxt) {
     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-    if ((*ctxt->input->cur == 0) &&
+    if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0) &&
         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
 	    xmlPopInput(ctxt);
 }
@@ -2620,7 +2768,7 @@
 	else
 	    c = 0;
     }
-    buffer[nbchars++] = 0;
+    buffer[nbchars] = 0;
     return(buffer);
 
 mem_error:
@@ -2923,12 +3071,15 @@
  *	Routines to parse Name, NCName and NmToken			*
  *									*
  ************************************************************************/
-unsigned long nbParseName = 0;
-unsigned long nbParseNmToken = 0;
-unsigned long nbParseNCName = 0;
-unsigned long nbParseNCNameComplex = 0;
-unsigned long nbParseNameComplex = 0;
-unsigned long nbParseStringName = 0;
+#ifdef DEBUG
+static unsigned long nbParseName = 0;
+static unsigned long nbParseNmToken = 0;
+static unsigned long nbParseNCName = 0;
+static unsigned long nbParseNCNameComplex = 0;
+static unsigned long nbParseNameComplex = 0;
+static unsigned long nbParseStringName = 0;
+#endif
+
 /*
  * The two following functions are related to the change of accepted
  * characters for Name and NmToken in the Revision 5 of XML-1.0
@@ -3018,7 +3169,9 @@
     int c;
     int count = 0;
 
+#ifdef DEBUG
     nbParseNameComplex++;
+#endif
 
     /*
      * Handler for more complex cases
@@ -3134,7 +3287,9 @@
 
     GROW;
 
+#ifdef DEBUG
     nbParseName++;
+#endif
 
     /*
      * Accelerator for simple ASCII names
@@ -3171,7 +3326,9 @@
     int c;
     int count = 0;
 
+#ifdef DEBUG
     nbParseNCNameComplex++;
+#endif
 
     /*
      * Handler for more complex cases
@@ -3217,7 +3374,9 @@
     const xmlChar *ret;
     int count = 0;
 
+#ifdef DEBUG
     nbParseNCName++;
+#endif
 
     /*
      * Accelerator for simple ASCII names
@@ -3312,7 +3471,9 @@
     int len = 0, l;
     int c;
 
+#ifdef DEBUG
     nbParseStringName++;
+#endif
 
     c = CUR_SCHAR(cur, l);
     if (!xmlIsNameStartChar(ctxt, c)) {
@@ -3386,7 +3547,9 @@
     int c;
     int count = 0;
 
+#ifdef DEBUG
     nbParseNmToken++;
+#endif
 
     GROW;
     c = CUR_CHAR(l);
@@ -3694,7 +3857,12 @@
 			if (rep != NULL) {
 			    current = rep;
 			    while (*current != 0) { /* non input consuming */
-				buf[len++] = *current++;
+                                if ((*current == 0xD) || (*current == 0xA) ||
+                                    (*current == 0x9)) {
+                                    buf[len++] = 0x20;
+                                    current++;
+                                } else
+                                    buf[len++] = *current++;
 				if (len > buf_size - 10) {
 				    growBuffer(buf, 10);
 				}
@@ -3984,7 +4152,7 @@
     return(buf);
 }
 
-void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
+static void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
 
 /*
  * used for the test in the inner loop of the char data testing
@@ -4189,7 +4357,7 @@
  * of xmlParseCharData() when the parsing requires handling
  * of non-ASCII characters.
  */
-void
+static void
 xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
     xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
     int nbchar = 0;
@@ -4790,7 +4958,8 @@
 		    (ctxt->sax->processingInstruction != NULL))
 		    ctxt->sax->processingInstruction(ctxt->userData,
 		                                     target, NULL);
-		ctxt->instate = state;
+		if (ctxt->instate != XML_PARSER_EOF)
+		    ctxt->instate = state;
 		return;
 	    }
 	    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
@@ -4870,7 +5039,8 @@
 	} else {
 	    xmlFatalErr(ctxt, XML_ERR_PI_NOT_STARTED, NULL);
 	}
-	ctxt->instate = state;
+	if (ctxt->instate != XML_PARSER_EOF)
+	    ctxt->instate = state;
     }
 }
 
@@ -5312,7 +5482,8 @@
 	if (name == NULL) {
 	    xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
 			   "Name expected in NOTATION declaration\n");
-	    return(ret);
+            xmlFreeEnumeration(ret);
+	    return(NULL);
 	}
 	tmp = ret;
 	while (tmp != NULL) {
@@ -5328,7 +5499,10 @@
 	}
 	if (tmp == NULL) {
 	    cur = xmlCreateEnumeration(name);
-	    if (cur == NULL) return(ret);
+	    if (cur == NULL) {
+                xmlFreeEnumeration(ret);
+                return(NULL);
+            }
 	    if (last == NULL) ret = last = cur;
 	    else {
 		last->next = cur;
@@ -5339,9 +5513,8 @@
     } while (RAW == '|');
     if (RAW != ')') {
 	xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
-	if ((last != NULL) && (last != ret))
-	    xmlFreeEnumeration(last);
-	return(ret);
+        xmlFreeEnumeration(ret);
+	return(NULL);
     }
     NEXT;
     return(ret);
@@ -5396,7 +5569,10 @@
 	    cur = xmlCreateEnumeration(name);
 	    if (!xmlDictOwns(ctxt->dict, name))
 		xmlFree(name);
-	    if (cur == NULL) return(ret);
+	    if (cur == NULL) {
+                xmlFreeEnumeration(ret);
+                return(NULL);
+            }
 	    if (last == NULL) ret = last = cur;
 	    else {
 		last->next = cur;
@@ -5744,7 +5920,8 @@
 		if (cur->c2 != NULL)
 		    cur->c2->parent = cur;
             }
-	    ret->ocur = XML_ELEMENT_CONTENT_MULT;
+            if (ret != NULL)
+                ret->ocur = XML_ELEMENT_CONTENT_MULT;
 	    if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
 		xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
 "Element content declaration doesn't start and stop in the same entity\n",
@@ -5764,9 +5941,10 @@
 }
 
 /**
- * xmlParseElementChildrenContentDecl:
+ * xmlParseElementChildrenContentDeclPriv:
  * @ctxt:  an XML parser context
  * @inputchk:  the input used for the current entity, needed for boundary checks
+ * @depth: the level of recursion
  *
  * parse the declaration for a Mixed Element content
  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
@@ -5794,12 +5972,20 @@
  * Returns the tree of xmlElementContentPtr describing the element 
  *          hierarchy.
  */
-xmlElementContentPtr
-xmlParseElementChildrenContentDecl (xmlParserCtxtPtr ctxt, int inputchk) {
+static xmlElementContentPtr
+xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk,
+                                       int depth) {
     xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
     const xmlChar *elem;
     xmlChar type = 0;
 
+    if (((depth > 128) && ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
+        (depth >  2048)) {
+        xmlFatalErrMsgInt(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED,
+"xmlParseElementChildrenContentDecl : depth %d too deep, use XML_PARSE_HUGE\n",
+                          depth);
+	return(NULL);
+    }
     SKIP_BLANKS;
     GROW;
     if (RAW == '(') {
@@ -5808,7 +5994,8 @@
         /* Recurse on first child */
 	NEXT;
 	SKIP_BLANKS;
-        cur = ret = xmlParseElementChildrenContentDecl(ctxt, inputid);
+        cur = ret = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
+                                                           depth + 1);
 	SKIP_BLANKS;
 	GROW;
     } else {
@@ -5940,7 +6127,8 @@
 	    /* Recurse on second child */
 	    NEXT;
 	    SKIP_BLANKS;
-	    last = xmlParseElementChildrenContentDecl(ctxt, inputid);
+	    last = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
+                                                          depth + 1);
 	    SKIP_BLANKS;
 	} else {
 	    elem = xmlParseName(ctxt);
@@ -6051,6 +6239,42 @@
 }
 
 /**
+ * xmlParseElementChildrenContentDecl:
+ * @ctxt:  an XML parser context
+ * @inputchk:  the input used for the current entity, needed for boundary checks
+ *
+ * parse the declaration for a Mixed Element content
+ * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
+ *
+ * [47] children ::= (choice | seq) ('?' | '*' | '+')?
+ *
+ * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
+ *
+ * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
+ *
+ * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
+ *
+ * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
+ * TODO Parameter-entity replacement text must be properly nested
+ *	with parenthesized groups. That is to say, if either of the
+ *	opening or closing parentheses in a choice, seq, or Mixed
+ *	construct is contained in the replacement text for a parameter
+ *	entity, both must be contained in the same replacement text. For
+ *	interoperability, if a parameter-entity reference appears in a
+ *	choice, seq, or Mixed construct, its replacement text should not
+ *	be empty, and neither the first nor last non-blank character of
+ *	the replacement text should be a connector (| or ,).
+ *
+ * Returns the tree of xmlElementContentPtr describing the element
+ *          hierarchy.
+ */
+xmlElementContentPtr
+xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
+    /* stub left for API/ABI compat */
+    return(xmlParseElementChildrenContentDeclPriv(ctxt, inputchk, 1));
+}
+
+/**
  * xmlParseElementContentDecl:
  * @ctxt:  an XML parser context
  * @name:  the name of the element being defined.
@@ -6086,7 +6310,7 @@
         tree = xmlParseElementMixedContentDecl(ctxt, inputid);
 	res = XML_ELEMENT_TYPE_MIXED;
     } else {
-        tree = xmlParseElementChildrenContentDecl(ctxt, inputid);
+        tree = xmlParseElementChildrenContentDeclPriv(ctxt, inputid, 1);
 	res = XML_ELEMENT_TYPE_ELEMENT;
     }
     SKIP_BLANKS;
@@ -6524,7 +6748,7 @@
     xmlDetectSAX2(ctxt);
     GROW;
 
-    if ((ctxt->encoding == (const xmlChar *)XML_CHAR_ENCODING_NONE) &&
+    if ((ctxt->encoding == NULL) &&
         (ctxt->input->end - ctxt->input->cur >= 4)) {
         xmlChar start[4];
 	xmlCharEncoding enc;
@@ -6779,6 +7003,7 @@
 		    ent->owner = 1;
 		    while (list != NULL) {
 			list->parent = (xmlNodePtr) ent;
+			xmlSetTreeDoc(list, ent->doc);
 			if (list->next == NULL)
 			    ent->last = list;
 			list = list->next;
@@ -7208,7 +7433,7 @@
  * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
  * is updated to the current location in the string.
  */
-xmlEntityPtr
+static xmlEntityPtr
 xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
     xmlChar *name;
     const xmlChar *ptr;
@@ -7223,7 +7448,6 @@
 	return(NULL);
 
     ptr++;
-    cur = *ptr;
     name = xmlParseStringName(ctxt, &ptr);
     if (name == NULL) {
 	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
@@ -7617,7 +7841,7 @@
  * Returns the string of the entity content.
  *         str is updated to the current value of the index
  */
-xmlEntityPtr
+static xmlEntityPtr
 xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
     const xmlChar *ptr;
     xmlChar cur;
@@ -7630,7 +7854,6 @@
     if (cur != '%')
         return(NULL);
     ptr++;
-    cur = *ptr;
     name = xmlParseStringName(ctxt, &ptr);
     if (name == NULL) {
 	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
@@ -8195,7 +8418,6 @@
 	        return(NULL);
 	    return(ctxt->nsTab[i + 1]);
 	}
-    if (ctxt->nsParent) return xmlGetNamespace(ctxt->nsParent, prefix);
     return(NULL);
 }
 
@@ -8295,7 +8517,7 @@
 static const xmlChar *
 xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
                         xmlChar const *prefix) {
-    const xmlChar *cmp = name;
+    const xmlChar *cmp;
     const xmlChar *in;
     const xmlChar *ret;
     const xmlChar *prefix2;
@@ -8304,7 +8526,7 @@
 
     GROW;
     in = ctxt->input->cur;
-    
+
     cmp = prefix;
     while (*in != 0 && *in == *cmp) {
     	++in;
@@ -9118,6 +9340,8 @@
      */
     if (name != (xmlChar*)1) {
         if (name == NULL) name = BAD_CAST "unparseable";
+        if ((line == 0) && (ctxt->node != NULL))
+            line = ctxt->node->line;
         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
 		     "Opening and ending tag mismatch: %s line %d and %s\n",
 		                ctxt->name, line, name);
@@ -9337,8 +9561,8 @@
 void
 xmlParseElement(xmlParserCtxtPtr ctxt) {
     const xmlChar *name;
-    const xmlChar *prefix;
-    const xmlChar *URI;
+    const xmlChar *prefix = NULL;
+    const xmlChar *URI = NULL;
     xmlParserNodeInfo node_info;
     int line, tlen;
     xmlNodePtr ret;
@@ -9376,6 +9600,8 @@
     else
 	name = xmlParseStartTag(ctxt);
 #endif /* LIBXML_SAX1_ENABLED */
+    if (ctxt->instate == XML_PARSER_EOF)
+	return;
     if (name == NULL) {
 	spacePop(ctxt);
         return;
@@ -9709,6 +9935,13 @@
 	} else {
 	    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
 	}
+
+        /*
+         * Non standard parsing, allowing the user to ignore encoding
+         */
+        if (ctxt->options & XML_PARSE_IGNORE_ENC)
+            return(encoding);
+
 	/*
 	 * UTF-16 encoding stwich has already taken place at this stage,
 	 * more over the little-endian/big-endian selection is already done
@@ -9937,6 +10170,12 @@
 	}
 	xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
     }
+
+    /*
+     * We can grow the input buffer freely at that point
+     */
+    GROW;
+
     SKIP_BLANKS;
     ctxt->input->standalone = xmlParseSDDecl(ctxt);
 
@@ -10015,7 +10254,7 @@
     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
         ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
 
-    if ((ctxt->encoding == (const xmlChar *)XML_CHAR_ENCODING_NONE) &&
+    if ((ctxt->encoding == NULL) &&
         ((ctxt->input->end - ctxt->input->cur) >= 4)) {
 	/* 
 	 * Get the 4 first bytes and decode the charset
@@ -10039,8 +10278,13 @@
 
     /*
      * Check for the XMLDecl in the Prolog.
+     * do not GROW here to avoid the detected encoder to decode more
+     * than just the first line, unless the amount of data is really
+     * too small to hold "<?xml version="1.0" encoding="foo"
      */
-    GROW;
+    if ((ctxt->input->end - ctxt->input->cur) < 35) {
+       GROW;
+    }
     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
 
 	/*
@@ -10707,8 +10951,8 @@
 		break;
             case XML_PARSER_START_TAG: {
 	        const xmlChar *name;
-		const xmlChar *prefix;
-		const xmlChar *URI;
+		const xmlChar *prefix = NULL;
+		const xmlChar *URI = NULL;
 		int nsNr = ctxt->nsNr;
 
 		if ((avail < 2) && (ctxt->inputNr == 1))
@@ -10744,6 +10988,8 @@
 		else
 		    name = xmlParseStartTag(ctxt);
 #endif /* LIBXML_SAX1_ENABLED */
+		if (ctxt->instate == XML_PARSER_EOF)
+		    goto done;
 		if (name == NULL) {
 		    spacePop(ctxt);
 		    ctxt->instate = XML_PARSER_EOF;
@@ -10930,7 +11176,9 @@
 		  else
 		    xmlParseEndTag1(ctxt, 0);
 #endif /* LIBXML_SAX1_ENABLED */
-		if (ctxt->nameNr == 0) {
+		if (ctxt->instate == XML_PARSER_EOF) {
+		    /* Nothing */
+		} else if (ctxt->nameNr == 0) {
 		    ctxt->instate = XML_PARSER_EPILOG;
 		} else {
 		    ctxt->instate = XML_PARSER_CONTENT;
@@ -11422,6 +11670,7 @@
 xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
               int terminate) {
     int end_in_lf = 0;
+    int remain = 0;
 
     if (ctxt == NULL)
         return(XML_ERR_INTERNAL_ERROR);
@@ -11434,12 +11683,50 @@
 	end_in_lf = 1;
 	size--;
     }
+
+xmldecl_done:
+
     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
         (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF))  {
 	int base = ctxt->input->base - ctxt->input->buf->buffer->content;
 	int cur = ctxt->input->cur - ctxt->input->base;
 	int res;
-	
+
+        /*
+         * Specific handling if we autodetected an encoding, we should not
+         * push more than the first line ... which depend on the encoding
+         * And only push the rest once the final encoding was detected
+         */
+        if ((ctxt->instate == XML_PARSER_START) && (ctxt->input != NULL) &&
+            (ctxt->input->buf != NULL) && (ctxt->input->buf->encoder != NULL)) {
+            unsigned int len = 45;
+
+            if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
+                               BAD_CAST "UTF-16")) ||
+                (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
+                               BAD_CAST "UTF16")))
+                len = 90;
+            else if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
+                                    BAD_CAST "UCS-4")) ||
+                     (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
+                                    BAD_CAST "UCS4")))
+                len = 180;
+
+            if (ctxt->input->buf->rawconsumed < len)
+                len -= ctxt->input->buf->rawconsumed;
+
+            /*
+             * Change size for reading the initial declaration only
+             * if size is greater than len. Otherwise, memmove in xmlBufferAdd
+             * will blindly copy extra bytes from memory.
+             */
+            if ((unsigned int) size > len) {
+                remain = size - len;
+                size = len;
+            } else {
+                remain = 0;
+            }
+        }
 	res =xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
 	if (res < 0) {
 	    ctxt->errNo = XML_PARSER_EOF;
@@ -11460,7 +11747,7 @@
 	    if ((in->encoder != NULL) && (in->buffer != NULL) &&
 		    (in->raw != NULL)) {
 		int nbchars;
-		    
+
 		nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
 		if (nbchars < 0) {
 		    /* TODO 2.6.0 */
@@ -11471,13 +11758,23 @@
 	    }
 	}
     }
-    xmlParseTryOrFinish(ctxt, terminate);
+    if (remain != 0)
+        xmlParseTryOrFinish(ctxt, 0);
+    else
+        xmlParseTryOrFinish(ctxt, terminate);
+    if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
+        return(ctxt->errNo);
+
+    if (remain != 0) {
+        chunk += size;
+        size = remain;
+        remain = 0;
+        goto xmldecl_done;
+    }
     if ((end_in_lf == 1) && (ctxt->input != NULL) &&
         (ctxt->input->buf != NULL)) {
 	xmlParserInputBufferPush(ctxt->input->buf, 1, "\r");
     }
-    if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
-        return(ctxt->errNo);
     if (terminate) {
 	/*
 	 * Check for termination
@@ -12041,8 +12338,6 @@
     int ret = 0;
     xmlChar start[4];
     xmlCharEncoding enc;
-    xmlParserInputPtr inputStream;
-    char *directory = NULL;
 
     if (ctx == NULL) return(-1);
 
@@ -12058,27 +12353,11 @@
     if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
 	return(-1);
 
-    ctxt = xmlNewParserCtxt();
+    ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, ctx);
     if (ctxt == NULL) {
 	return(-1);
     }
 
-    ctxt->userData = ctxt;
-    ctxt->_private = ctx->_private;
-
-    inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
-    if (inputStream == NULL) {
-	xmlFreeParserCtxt(ctxt);
-	return(-1);
-    }
-
-    inputPush(ctxt, inputStream);
-
-    if ((ctxt->directory == NULL) && (directory == NULL))
-	directory = xmlParserGetDirectory((char *)URL);
-    if ((ctxt->directory == NULL) && (directory != NULL))
-	ctxt->directory = directory;
-
     oldsax = ctxt->sax;
     ctxt->sax = ctx->sax;
     xmlDetectSAX2(ctxt);
@@ -12271,7 +12550,7 @@
 	return(XML_ERR_INTERNAL_ERROR);
 
 
-    ctxt = xmlCreateEntityParserCtxt(URL, ID, NULL);
+    ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, oldctxt);
     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
     ctxt->userData = ctxt;
     if (oldctxt != NULL) {
@@ -12401,7 +12680,9 @@
      * Record in the parent context the number of entities replacement
      * done when parsing that reference.
      */
-    oldctxt->nbentities += ctxt->nbentities;
+    if (oldctxt != NULL)
+        oldctxt->nbentities += ctxt->nbentities;
+
     /*
      * Also record the size of the entity parsed
      */
@@ -12519,6 +12800,9 @@
     xmlNodePtr last = NULL;
     int size;
     xmlParserErrors ret = XML_ERR_OK;
+#ifdef SAX2
+    int i;
+#endif
 
     if (((oldctxt->depth > 40) && ((oldctxt->options & XML_PARSE_HUGE) == 0)) ||
         (oldctxt->depth >  1024)) {
@@ -12545,7 +12829,12 @@
     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
 
-    ctxt->nsParent = oldctxt;
+#ifdef SAX2
+    /* propagate namespaces down the entity */
+    for (i = 0;i < oldctxt->nsNr;i += 2) {
+        nsPush(ctxt, oldctxt->nsTab[i], oldctxt->nsTab[i+1]);
+    }
+#endif
 
     oldsax = ctxt->sax;
     ctxt->sax = oldctxt->sax;
@@ -12652,7 +12941,9 @@
      * Record in the parent context the number of entities replacement
      * done when parsing that reference.
      */
-    oldctxt->nbentities += ctxt->nbentities;
+    if (oldctxt != NULL)
+        oldctxt->nbentities += ctxt->nbentities;
+
     /*
      * Also record the last error if any
      */
@@ -12741,22 +13032,22 @@
     if (doc->type == XML_DOCUMENT_NODE)
 	ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen);
 #ifdef LIBXML_HTML_ENABLED
-    else if (doc->type == XML_HTML_DOCUMENT_NODE)
+    else if (doc->type == XML_HTML_DOCUMENT_NODE) {
 	ctxt = htmlCreateMemoryParserCtxt((char *) data, datalen);
+        /*
+         * When parsing in context, it makes no sense to add implied
+         * elements like html/body/etc...
+         */
+        options |= HTML_PARSE_NOIMPLIED;
+    }
 #endif
     else
         return(XML_ERR_INTERNAL_ERROR);
 
     if (ctxt == NULL)
         return(XML_ERR_NO_MEMORY);
-    fake = xmlNewComment(NULL);
-    if (fake == NULL) {
-        xmlFreeParserCtxt(ctxt);
-	return(XML_ERR_NO_MEMORY);
-    }
-    xmlAddChild(node, fake);
 
-    /* 
+    /*
      * Use input doc's dict if present, else assure XML_PARSE_NODICT is set.
      * We need a dictionary for xmlDetectSAX2, so if there's no doc dict
      * we must wait until the last moment to free the original one.
@@ -12768,10 +13059,32 @@
     } else
         options |= XML_PARSE_NODICT;
 
+    if (doc->encoding != NULL) {
+        xmlCharEncodingHandlerPtr hdlr;
+
+        if (ctxt->encoding != NULL)
+	    xmlFree((xmlChar *) ctxt->encoding);
+        ctxt->encoding = xmlStrdup((const xmlChar *) doc->encoding);
+
+        hdlr = xmlFindCharEncodingHandler(doc->encoding);
+        if (hdlr != NULL) {
+            xmlSwitchToEncoding(ctxt, hdlr);
+	} else {
+            return(XML_ERR_UNSUPPORTED_ENCODING);
+        }
+    }
+
     xmlCtxtUseOptionsInternal(ctxt, options, NULL);
     xmlDetectSAX2(ctxt);
     ctxt->myDoc = doc;
 
+    fake = xmlNewComment(NULL);
+    if (fake == NULL) {
+        xmlFreeParserCtxt(ctxt);
+	return(XML_ERR_NO_MEMORY);
+    }
+    xmlAddChild(node, fake);
+
     if (node->type == XML_ELEMENT_NODE) {
 	nodePush(ctxt, node);
 	/*
@@ -13108,10 +13421,11 @@
 #endif /* LIBXML_SAX1_ENABLED */
 
 /**
- * xmlCreateEntityParserCtxt:
+ * xmlCreateEntityParserCtxtInternal:
  * @URL:  the entity URL
  * @ID:  the entity PUBLIC ID
  * @base:  a possible base for the target URI
+ * @pctx:  parser context used to set options on new context
  *
  * Create a parser context for an external entity
  * Automatic support for ZLIB/Compress compressed document is provided
@@ -13119,9 +13433,9 @@
  *
  * Returns the new parser context or NULL
  */
-xmlParserCtxtPtr
-xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
-	                  const xmlChar *base) {
+static xmlParserCtxtPtr
+xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
+	                  const xmlChar *base, xmlParserCtxtPtr pctx) {
     xmlParserCtxtPtr ctxt;
     xmlParserInputPtr inputStream;
     char *directory = NULL;
@@ -13132,6 +13446,11 @@
 	return(NULL);
     }
 
+    if (pctx != NULL) {
+        ctxt->options = pctx->options;
+        ctxt->_private = pctx->_private;
+    }
+
     uri = xmlBuildURI(URL, base);
 
     if (uri == NULL) {
@@ -13166,6 +13485,25 @@
     return(ctxt);
 }
 
+/**
+ * xmlCreateEntityParserCtxt:
+ * @URL:  the entity URL
+ * @ID:  the entity PUBLIC ID
+ * @base:  a possible base for the target URI
+ *
+ * Create a parser context for an external entity
+ * Automatic support for ZLIB/Compress compressed document is provided
+ * by default if found at compile-time.
+ *
+ * Returns the new parser context or NULL
+ */
+xmlParserCtxtPtr
+xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
+	                  const xmlChar *base) {
+    return xmlCreateEntityParserCtxtInternal(URL, ID, base, NULL);
+
+}
+
 /************************************************************************
  *									*
  *		Front ends when parsing from a file			*
@@ -13334,7 +13672,7 @@
  */
 
 xmlDocPtr
-xmlRecoverDoc(xmlChar *cur) {
+xmlRecoverDoc(const xmlChar *cur) {
     return(xmlSAXParseDoc(NULL, cur, 1));
 }
 
@@ -13536,6 +13874,8 @@
     xmlDocPtr ret;
     xmlParserCtxtPtr ctxt;
 
+    xmlInitParser();
+
     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
     if (ctxt == NULL) return(NULL);
     if (sax != NULL) {
@@ -13561,7 +13901,7 @@
     if (sax != NULL) 
 	ctxt->sax = NULL;
     xmlFreeParserCtxt(ctxt);
-    
+
     return(ret);
 }
 
@@ -13624,14 +13964,16 @@
  *
  * A better SAX parsing routine.
  * parse an XML in-memory buffer and call the given SAX handler routines.
- * 
+ *
  * Returns 0 in case of success or a error number otherwise
  */
 int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
 			  const char *buffer, int size) {
     int ret = 0;
     xmlParserCtxtPtr ctxt;
-    
+
+    xmlInitParser();
+
     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
     if (ctxt == NULL) return -1;
     if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
@@ -13641,7 +13983,7 @@
 
     if (user_data != NULL)
 	ctxt->userData = user_data;
-    
+
     xmlParseDocument(ctxt);
     
     if (ctxt->wellFormed)
@@ -13815,11 +14157,11 @@
     __xmlGlobalInitMutexLock();
     if (xmlParserInitialized == 0) {
 #endif
+	xmlInitThreads();
+	xmlInitGlobals();
 	if ((xmlGenericError == xmlGenericErrorDefaultFunc) ||
 	    (xmlGenericError == NULL))
 	    initGenericErrorDefaultFunc(NULL);
-	xmlInitGlobals();
-	xmlInitThreads();
 	xmlInitMemory();
 	xmlInitCharEncodingHandlers();
 	xmlDefaultSAXHandlerInit();
@@ -13853,6 +14195,14 @@
  * the library and all XML/HTML documents built with it.
  * See also xmlInitParser() which has the opposite function of preparing
  * the library for operations.
+ *
+ * WARNING: if your application is multithreaded or has plugin support
+ *          calling this may crash the application if another thread or
+ *          a plugin is still using libxml2. It's sometimes very hard to
+ *          guess if libxml2 is in use in the application, some libraries
+ *          or plugins may use it without notice. In case of doubt abstain
+ *          from calling this function or do it just before calling exit()
+ *          to avoid leak reports from valgrind !
  */
 
 void
@@ -14235,6 +14585,10 @@
 	ctxt->options |= XML_PARSE_OLDSAX;
         options -= XML_PARSE_OLDSAX;
     }
+    if (options & XML_PARSE_IGNORE_ENC) {
+	ctxt->options |= XML_PARSE_IGNORE_ENC;
+        options -= XML_PARSE_IGNORE_ENC;
+    }
     ctxt->linenumbers = 1;
     return (options);
 }
diff --git a/parserInternals.c b/parserInternals.c
index 758c6b3..2404ddf 100644
--- a/parserInternals.c
+++ b/parserInternals.c
@@ -494,20 +494,26 @@
             if (c & 0x80) {
 	        if (c == 0xC0)
 		    goto encoding_error;
-                if (cur[1] == 0)
+                if (cur[1] == 0) {
                     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+                    cur = ctxt->input->cur;
+                }
                 if ((cur[1] & 0xc0) != 0x80)
                     goto encoding_error;
                 if ((c & 0xe0) == 0xe0) {
                     unsigned int val;
 
-                    if (cur[2] == 0)
+                    if (cur[2] == 0) {
                         xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+                        cur = ctxt->input->cur;
+                    }
                     if ((cur[2] & 0xc0) != 0x80)
                         goto encoding_error;
                     if ((c & 0xf0) == 0xf0) {
-                        if (cur[3] == 0)
+                        if (cur[3] == 0) {
                             xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+                            cur = ctxt->input->cur;
+                        }
                         if (((c & 0xf8) != 0xf0) ||
                             ((cur[3] & 0xc0) != 0x80))
                             goto encoding_error;
@@ -640,18 +646,24 @@
 	if (c & 0x80) {
 	    if (((c & 0x40) == 0) || (c == 0xC0))
 		goto encoding_error;
-	    if (cur[1] == 0)
+	    if (cur[1] == 0) {
 		xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+                cur = ctxt->input->cur;
+            }
 	    if ((cur[1] & 0xc0) != 0x80)
 		goto encoding_error;
 	    if ((c & 0xe0) == 0xe0) {
-		if (cur[2] == 0)
+		if (cur[2] == 0) {
 		    xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+                    cur = ctxt->input->cur;
+                }
 		if ((cur[2] & 0xc0) != 0x80)
 		    goto encoding_error;
 		if ((c & 0xf0) == 0xf0) {
-		    if (cur[3] == 0)
+		    if (cur[3] == 0) {
 			xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+                        cur = ctxt->input->cur;
+                    }
 		    if (((c & 0xf8) != 0xf0) ||
 			((cur[3] & 0xc0) != 0x80))
 			goto encoding_error;
@@ -933,6 +945,17 @@
  *									*
  ************************************************************************/
 
+/* defined in encoding.c, not public */
+int
+xmlCharEncFirstLineInt(xmlCharEncodingHandler *handler, xmlBufferPtr out,
+                       xmlBufferPtr in, int len);
+
+static int
+xmlSwitchToEncodingInt(xmlParserCtxtPtr ctxt,
+                       xmlCharEncodingHandlerPtr handler, int len);
+static int
+xmlSwitchInputEncodingInt(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
+                          xmlCharEncodingHandlerPtr handler, int len);
 /**
  * xmlSwitchEncoding:
  * @ctxt:  the parser context
@@ -947,6 +970,7 @@
 xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
 {
     xmlCharEncodingHandlerPtr handler;
+    int len = -1;
 
     if (ctxt == NULL) return(-1);
     switch (enc) {
@@ -990,9 +1014,33 @@
             (ctxt->input->cur[2] == 0xBF)) {
             ctxt->input->cur += 3;
         }
-	break ;
-	default:
-	    break;
+        len = 90;
+	break;
+    case XML_CHAR_ENCODING_UCS2:
+        len = 90;
+	break;
+    case XML_CHAR_ENCODING_UCS4BE:
+    case XML_CHAR_ENCODING_UCS4LE:
+    case XML_CHAR_ENCODING_UCS4_2143:
+    case XML_CHAR_ENCODING_UCS4_3412:
+        len = 180;
+	break;
+    case XML_CHAR_ENCODING_EBCDIC:
+    case XML_CHAR_ENCODING_8859_1:
+    case XML_CHAR_ENCODING_8859_2:
+    case XML_CHAR_ENCODING_8859_3:
+    case XML_CHAR_ENCODING_8859_4:
+    case XML_CHAR_ENCODING_8859_5:
+    case XML_CHAR_ENCODING_8859_6:
+    case XML_CHAR_ENCODING_8859_7:
+    case XML_CHAR_ENCODING_8859_8:
+    case XML_CHAR_ENCODING_8859_9:
+    case XML_CHAR_ENCODING_ASCII:
+    case XML_CHAR_ENCODING_2022_JP:
+    case XML_CHAR_ENCODING_SHIFT_JIS:
+    case XML_CHAR_ENCODING_EUC_JP:
+        len = 45;
+	break;
     }
     handler = xmlGetCharEncodingHandler(enc);
     if (handler == NULL) {
@@ -1083,7 +1131,7 @@
     if (handler == NULL)
 	return(-1);
     ctxt->charset = XML_CHAR_ENCODING_UTF8;
-    return(xmlSwitchToEncoding(ctxt, handler));
+    return(xmlSwitchToEncodingInt(ctxt, handler, len));
 }
 
 /**
@@ -1091,15 +1139,16 @@
  * @ctxt:  the parser context
  * @input:  the input stream
  * @handler:  the encoding handler
+ * @len:  the number of bytes to convert for the first line or -1
  *
  * change the input functions when discovering the character encoding
  * of a given entity.
  *
  * Returns 0 in case of success, -1 otherwise
  */
-int
-xmlSwitchInputEncoding(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
-                       xmlCharEncodingHandlerPtr handler)
+static int
+xmlSwitchInputEncodingInt(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
+                          xmlCharEncodingHandlerPtr handler, int len)
 {
     int nbchars;
 
@@ -1196,9 +1245,10 @@
                  * parsed with the autodetected encoding
                  * into the parser reading buffer.
                  */
-                nbchars = xmlCharEncFirstLine(input->buf->encoder,
-                                              input->buf->buffer,
-                                              input->buf->raw);
+                nbchars = xmlCharEncFirstLineInt(input->buf->encoder,
+                                                 input->buf->buffer,
+                                                 input->buf->raw,
+                                                 len);
             }
             if (nbchars < 0) {
                 xmlErrInternal(ctxt,
@@ -1224,6 +1274,58 @@
 }
 
 /**
+ * xmlSwitchInputEncoding:
+ * @ctxt:  the parser context
+ * @input:  the input stream
+ * @handler:  the encoding handler
+ *
+ * change the input functions when discovering the character encoding
+ * of a given entity.
+ *
+ * Returns 0 in case of success, -1 otherwise
+ */
+int
+xmlSwitchInputEncoding(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
+                          xmlCharEncodingHandlerPtr handler) {
+    return(xmlSwitchInputEncodingInt(ctxt, input, handler, -1));
+}
+
+/**
+ * xmlSwitchToEncodingInt:
+ * @ctxt:  the parser context
+ * @handler:  the encoding handler
+ * @len: the lenght to convert or -1
+ *
+ * change the input functions when discovering the character encoding
+ * of a given entity, and convert only @len bytes of the output, this
+ * is needed on auto detect to allows any declared encoding later to
+ * convert the actual content after the xmlDecl
+ *
+ * Returns 0 in case of success, -1 otherwise
+ */
+static int
+xmlSwitchToEncodingInt(xmlParserCtxtPtr ctxt,
+                       xmlCharEncodingHandlerPtr handler, int len) {
+    int ret = 0;
+
+    if (handler != NULL) {
+        if (ctxt->input != NULL) {
+	    ret = xmlSwitchInputEncodingInt(ctxt, ctxt->input, handler, len);
+	} else {
+	    xmlErrInternal(ctxt, "xmlSwitchToEncoding : no input\n",
+	                   NULL);
+	    return(-1);
+	}
+	/*
+	 * The parsing is now done in UTF8 natively
+	 */
+	ctxt->charset = XML_CHAR_ENCODING_UTF8;
+    } else
+	return(-1);
+    return(ret);
+}
+
+/**
  * xmlSwitchToEncoding:
  * @ctxt:  the parser context
  * @handler:  the encoding handler
@@ -1236,23 +1338,7 @@
 int
 xmlSwitchToEncoding(xmlParserCtxtPtr ctxt, xmlCharEncodingHandlerPtr handler) 
 {
-    int ret = 0;
-
-    if (handler != NULL) {
-        if (ctxt->input != NULL) {
-	    ret = xmlSwitchInputEncoding(ctxt, ctxt->input, handler);
-	} else {
-	    xmlErrInternal(ctxt, "xmlSwitchToEncoding : no input\n",
-	                   NULL);
-	    return(-1);
-	}
-	/*
-	 * The parsing is now done in UTF8 natively
-	 */
-	ctxt->charset = XML_CHAR_ENCODING_UTF8;
-    } else 
-	return(-1);
-    return(ret);
+    return (xmlSwitchToEncodingInt(ctxt, handler, -1));
 }
 
 /************************************************************************
@@ -1696,6 +1782,7 @@
     if (ctxt->spaceTab != NULL) xmlFree(ctxt->spaceTab);
     if (ctxt->nameTab != NULL) xmlFree((xmlChar * *)ctxt->nameTab);
     if (ctxt->nodeTab != NULL) xmlFree(ctxt->nodeTab);
+    if (ctxt->nodeInfoTab != NULL) xmlFree(ctxt->nodeInfoTab);
     if (ctxt->inputTab != NULL) xmlFree(ctxt->inputTab);
     if (ctxt->version != NULL) xmlFree((char *) ctxt->version);
     if (ctxt->encoding != NULL) xmlFree((char *) ctxt->encoding);
@@ -2067,7 +2154,7 @@
     int old = xmlKeepBlanksDefaultValue;
 
     xmlKeepBlanksDefaultValue = val;
-    xmlIndentTreeOutput = !val;
+    if (!val) xmlIndentTreeOutput = 1;
     return(old);
 }
 
diff --git a/relaxng.c b/relaxng.c
index 6459769..f575287 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -149,6 +149,7 @@
 #define IS_PROCESSED		(1 << 5)
 #define IS_COMPILABLE		(1 << 6)
 #define IS_NOT_COMPILABLE	(1 << 7)
+#define IS_EXTERNAL_REF	        (1 << 8)
 
 struct _xmlRelaxNGDefine {
     xmlRelaxNGType type;        /* the type of definition */
@@ -414,6 +415,7 @@
     xmlDocPtr doc;              /* the associated XML document */
     xmlRelaxNGDefinePtr content;        /* the definitions */
     xmlRelaxNGPtr schema;       /* the schema */
+    int externalRef;            /* 1 if an external ref */
 };
 
 
@@ -1006,7 +1008,7 @@
     xmlRelaxNGStatesPtr ret;
 
     if ((ctxt != NULL) &&
-        (ctxt->freeState != NULL) && (ctxt->freeStatesNr > 0)) {
+        (ctxt->freeStates != NULL) && (ctxt->freeStatesNr > 0)) {
         ctxt->freeStatesNr--;
         ret = ctxt->freeStates[ctxt->freeStatesNr];
         ret->nbState = 0;
@@ -1559,8 +1561,8 @@
                     href = xmlGetProp(tmp, BAD_CAST "href");
 #endif
                     if (xmlRelaxNGRemoveRedefine(ctxt, href,
-                                                 inc->doc->children->
-                                                 children, name) == 1) {
+                                                 xmlDocGetRootElement(inc->doc)->children,
+                                                 name) == 1) {
                         found = 1;
                     }
 #ifdef DEBUG_INCLUDE
@@ -1970,6 +1972,7 @@
     ret->doc = doc;
     ret->href = xmlStrdup(URL);
     ret->next = ctxt->documents;
+    ret->externalRef = 1;
     ctxt->documents = ret;
 
     /*
@@ -2372,6 +2375,9 @@
         } else {
             node = seq = NULL;
         }
+        if ((node == NULL) && (seq == NULL)) {
+            node = ctxt->pnode;
+        }
         xmlRelaxNGShowValidError(ctxt, err, node, seq, arg1, arg2);
     }
     /*
@@ -2849,6 +2855,10 @@
  * 									*
  ************************************************************************/
 
+/* from automata.c but not exported */
+void xmlAutomataSetFlags(xmlAutomataPtr am, int flags);
+
+
 static int xmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt,
                                 xmlRelaxNGDefinePtr def);
 
@@ -3032,6 +3042,17 @@
                 ctxt->am = xmlNewAutomata();
                 if (ctxt->am == NULL)
                     return (-1);
+
+                /*
+                 * assume identical strings but not same pointer are different
+                 * atoms, needed for non-determinism detection
+                 * That way if 2 elements with the same name are in a choice
+                 * branch the automata is found non-deterministic and
+                 * we fallback to the normal validation which does the right
+                 * thing of exploring both choices.
+                 */
+                xmlAutomataSetFlags(ctxt->am, 1);
+
                 ctxt->state = xmlAutomataGetInitState(ctxt->am);
                 while (list != NULL) {
                     xmlRelaxNGCompile(ctxt, list);
@@ -3063,6 +3084,7 @@
                 ctxt->am = xmlNewAutomata();
                 if (ctxt->am == NULL)
                     return (-1);
+                xmlAutomataSetFlags(ctxt->am, 1);
                 ctxt->state = xmlAutomataGetInitState(ctxt->am);
                 while (list != NULL) {
                     xmlRelaxNGCompile(ctxt, list);
@@ -3071,6 +3093,11 @@
                 xmlAutomataSetFinalState(ctxt->am, ctxt->state);
                 def->contModel = xmlAutomataCompile(ctxt->am);
                 if (!xmlRegexpIsDeterminist(def->contModel)) {
+#ifdef DEBUG_COMPILE
+                    xmlGenericError(xmlGenericErrorContext,
+                        "Content model not determinist %s\n",
+                                    def->name);
+#endif
                     /*
                      * we can only use the automata if it is determinist
                      */
@@ -3098,7 +3125,11 @@
         case XML_RELAXNG_OPTIONAL:{
                 xmlAutomataStatePtr oldstate = ctxt->state;
 
-                xmlRelaxNGCompile(ctxt, def->content);
+                list = def->content;
+                while (list != NULL) {
+                    xmlRelaxNGCompile(ctxt, list);
+                    list = list->next;
+                }
                 xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
                 break;
             }
@@ -3440,6 +3471,9 @@
 {
     xmlChar *ret, *escape;
 
+    if (node == NULL)
+        return(NULL);
+
     if ((IS_RELAXNG(node, "data")) || (IS_RELAXNG(node, "value"))) {
         ret = xmlGetProp(node, BAD_CAST "datatypeLibrary");
         if (ret != NULL) {
@@ -4616,6 +4650,72 @@
 }
 
 /**
+ * xmlRelaxNGParseImportRef:
+ * @payload: the parser context
+ * @data: the current grammar
+ * @name: the reference name
+ *
+ * Import import one references into the current grammar
+ */
+static void
+xmlRelaxNGParseImportRef(void *payload, void *data, xmlChar *name) {
+    xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data;
+    xmlRelaxNGDefinePtr def = (xmlRelaxNGDefinePtr) payload;
+    int tmp;
+
+    def->dflags |= IS_EXTERNAL_REF;
+
+    tmp = xmlHashAddEntry(ctxt->grammar->refs, name, def);
+    if (tmp < 0) {
+        xmlRelaxNGDefinePtr prev;
+
+        prev = (xmlRelaxNGDefinePtr)
+            xmlHashLookup(ctxt->grammar->refs, def->name);
+        if (prev == NULL) {
+            if (def->name != NULL) {
+                xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
+                           "Error refs definitions '%s'\n",
+                           def->name, NULL);
+            } else {
+                xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
+                           "Error refs definitions\n",
+                           NULL, NULL);
+            }
+        } else {
+            def->nextHash = prev->nextHash;
+            prev->nextHash = def;
+        }
+    }
+}
+
+/**
+ * xmlRelaxNGParseImportRefs:
+ * @ctxt: the parser context
+ * @grammar: the sub grammar
+ *
+ * Import references from the subgrammar into the current grammar
+ *
+ * Returns 0 in case of success, -1 in case of failure
+ */
+static int
+xmlRelaxNGParseImportRefs(xmlRelaxNGParserCtxtPtr ctxt,
+                          xmlRelaxNGGrammarPtr grammar) {
+    if ((ctxt == NULL) || (grammar == NULL) || (ctxt->grammar == NULL))
+        return(-1);
+    if (grammar->refs == NULL)
+        return(0);
+    if (ctxt->grammar->refs == NULL)
+        ctxt->grammar->refs = xmlHashCreate(10);
+    if (ctxt->grammar->refs == NULL) {
+        xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
+                   "Could not create references hash\n", NULL, NULL);
+        return(-1);
+    }
+    xmlHashScan(grammar->refs, xmlRelaxNGParseImportRef, ctxt);
+    return(0);
+}
+
+/**
  * xmlRelaxNGProcessExternalRef:
  * @ctxt: the parser context
  * @node:  the externlRef node
@@ -4683,6 +4783,8 @@
             if ((docu->schema != NULL) &&
                 (docu->schema->topgrammar != NULL)) {
                 docu->content = docu->schema->topgrammar->start;
+                if (docu->schema->topgrammar->refs)
+                    xmlRelaxNGParseImportRefs(ctxt, docu->schema->topgrammar);
             }
 
             /*
@@ -5267,7 +5369,8 @@
     } else {
         xmlRngPErr(ctxt, node, XML_RNGP_CHOICE_CONTENT,
                    "expecting name, anyName, nsName or choice : got %s\n",
-                   node->name, NULL);
+                   (node == NULL ? (const xmlChar *) "nothing" : node->name),
+		   NULL);
         return (NULL);
     }
     if (ret != def) {
@@ -5569,6 +5672,12 @@
     xmlRelaxNGGrammarPtr grammar;
     xmlRelaxNGDefinePtr def, cur;
 
+    /*
+     * Those rules don't apply to imported ref from xmlRelaxNGParseImportRef
+     */
+    if (ref->dflags & IS_EXTERNAL_REF)
+        return;
+
     grammar = ctxt->grammar;
     if (grammar == NULL) {
         xmlRngPErr(ctxt, ref->node, XML_ERR_INTERNAL_ERROR,
@@ -6133,7 +6242,7 @@
                      xmlRelaxNGDefinePtr cur, int flags,
                      xmlRelaxNGType ptype)
 {
-    int nflags = flags;
+    int nflags;
     xmlRelaxNGContentType ret, tmp, val = XML_RELAXNG_CONTENT_EMPTY;
 
     while (cur != NULL) {
@@ -6157,6 +6266,16 @@
                            "Found forbidden pattern data/except//ref\n",
                            NULL, NULL);
             }
+            if (cur->content == NULL) {
+                if (cur->type == XML_RELAXNG_PARENTREF)
+                    xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_NO_DEF,
+                               "Internal found no define for parent refs\n",
+                               NULL, NULL);
+                else
+                    xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_NO_DEF,
+                               "Internal found no define for ref %s\n",
+                               (cur->name ? cur->name: BAD_CAST "null"), NULL);
+            }
             if (cur->depth > -4) {
                 cur->depth = -4;
                 ret = xmlRelaxNGCheckRules(ctxt, cur->content,
@@ -6408,6 +6527,10 @@
         if (ptype == XML_RELAXNG_GROUP) {
             val = xmlRelaxNGGroupContentType(val, ret);
         } else if (ptype == XML_RELAXNG_INTERLEAVE) {
+            /*
+             * TODO: scan complain that tmp is never used, seems on purpose
+             *       need double-checking
+             */
             tmp = xmlRelaxNGGroupContentType(val, ret);
             if (tmp != XML_RELAXNG_CONTENT_ERROR)
                 tmp = xmlRelaxNGMaxContentType(val, ret);
@@ -6495,6 +6618,7 @@
                     ctxt);
     }
 
+
     /* @@@@ */
 
     ctxt->grammar = old;
@@ -8345,7 +8469,7 @@
         ret = -1;
     else
         ret = 1;
-    xmlRelaxNGFreeValidState(ctxt, state);
+    xmlRelaxNGFreeValidState(ctxt, ctxt->state);
     ctxt->state = NULL;
 #ifdef DEBUG_PROGRESSIVE
     if (ret < 0)
@@ -8760,6 +8884,11 @@
         case XML_RELAXNG_ZEROORMORE:{
                 xmlChar *cur, *temp;
 
+                if ((ctxt->state->value == NULL) ||
+                    (*ctxt->state->value == 0)) {
+                    ret = 0;
+                    break;
+                }
                 oldflags = ctxt->flags;
                 ctxt->flags |= FLAGS_IGNORABLE;
                 cur = ctxt->state->value;
@@ -8781,6 +8910,30 @@
 		    xmlRelaxNGPopErrors(ctxt, 0);
                 break;
             }
+        case XML_RELAXNG_OPTIONAL:{
+                xmlChar *temp;
+
+                if ((ctxt->state->value == NULL) ||
+                    (*ctxt->state->value == 0)) {
+                    ret = 0;
+                    break;
+                }
+                oldflags = ctxt->flags;
+                ctxt->flags |= FLAGS_IGNORABLE;
+                temp = ctxt->state->value;
+                ret = xmlRelaxNGValidateValue(ctxt, define->content);
+                ctxt->flags = oldflags;
+                if (ret != 0) {
+                    ctxt->state->value = temp;
+                    if (ctxt->errNr > 0)
+                        xmlRelaxNGPopErrors(ctxt, 0);
+                    ret = 0;
+                    break;
+                }
+		if (ctxt->errNr > 0)
+		    xmlRelaxNGPopErrors(ctxt, 0);
+                break;
+            }
         case XML_RELAXNG_EXCEPT:{
                 xmlRelaxNGDefinePtr list;
 
@@ -8815,8 +8968,11 @@
         case XML_RELAXNG_REF:
         case XML_RELAXNG_PARENTREF:
 	    if (define->content == NULL) {
-	    }
-            ret = xmlRelaxNGValidateValue(ctxt, define->content);
+                VALID_ERR(XML_RELAXNG_ERR_NODEFINE);
+                ret = -1;
+	    } else {
+                ret = xmlRelaxNGValidateValue(ctxt, define->content);
+            }
             break;
         default:
             TODO ret = -1;
@@ -9323,6 +9479,7 @@
 		    oldstate =
 			ctxt->states->tabState[ctxt->states->nbState - 1];
                     ctxt->states->tabState[ctxt->states->nbState - 1] = NULL;
+                    ctxt->states->nbState--;
 		}
             }
             for (j = 0; j < ctxt->states->nbState ; j++) {
@@ -9331,7 +9488,12 @@
             xmlRelaxNGFreeStates(ctxt, ctxt->states);
             ctxt->states = NULL;
             if (found == 0) {
-                VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA, cur->name);
+                if (cur == NULL) {
+		    VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA,
+			       (const xmlChar *) "noname");
+                } else {
+                    VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA, cur->name);
+                }
                 ret = -1;
                 ctxt->state = oldstate;
                 goto done;
@@ -9878,8 +10040,8 @@
                     }
                     for (i = 0; i < ctxt->states->nbState; i++) {
                         xmlRelaxNGFreeValidState(ctxt,
-                                                 ctxt->states->
-                                                 tabState[i]);
+                                                 ctxt->states->tabState[i]);
+                        ctxt->states->tabState[i] = NULL;
                     }
                     xmlRelaxNGFreeStates(ctxt, ctxt->states);
                     ctxt->flags = oldflags;
@@ -10001,11 +10163,8 @@
                 } else {
                     for (j = 0; j < ctxt->states->nbState; j++) {
                         xmlRelaxNGAddStates(ctxt, res,
-                                            xmlRelaxNGCopyValidState(ctxt,
-                                                                     ctxt->
-                                                                     states->
-                                                                     tabState
-                                                                     [j]));
+                            xmlRelaxNGCopyValidState(ctxt,
+                                            ctxt->states->tabState[j]));
                     }
                 }
                 oldflags = ctxt->flags;
@@ -10034,10 +10193,7 @@
                                          j++) {
                                         tmp =
                                             xmlRelaxNGAddStates(ctxt, res,
-                                                                ctxt->
-                                                                states->
-                                                                tabState
-                                                                [j]);
+                                                   ctxt->states->tabState[j]);
                                         if (tmp == 1)
                                             progress = 1;
                                     }
@@ -10071,9 +10227,7 @@
                             } else if (ctxt->states != NULL) {
                                 for (j = 0; j < ctxt->states->nbState; j++) {
                                     tmp = xmlRelaxNGAddStates(ctxt, res,
-                                                              ctxt->
-                                                              states->
-                                                              tabState[j]);
+                                               ctxt->states->tabState[j]);
                                     if (tmp == 1)
                                         progress = 1;
                                 }
@@ -10111,8 +10265,7 @@
                             for (i = base; i < res->nbState; i++)
                                 xmlRelaxNGAddStates(ctxt, states,
                                                     xmlRelaxNGCopyValidState
-                                                    (ctxt,
-                                                     res->tabState[i]));
+                                                    (ctxt, res->tabState[i]));
                             ctxt->states = states;
                         }
                     }
@@ -10634,6 +10787,60 @@
     return (ret);
 }
 
+/**
+ * xmlRelaxNGCleanPSVI:
+ * @node:  an input element or document
+ *
+ * Call this routine to speed up XPath computation on static documents.
+ * This stamps all the element nodes with the document order
+ * Like for line information, the order is kept in the element->content
+ * field, the value stored is actually - the node number (starting at -1)
+ * to be able to differentiate from line numbers.
+ *
+ * Returns the number of elements found in the document or -1 in case
+ *    of error.
+ */
+static void
+xmlRelaxNGCleanPSVI(xmlNodePtr node) {
+    xmlNodePtr cur;
+
+    if ((node == NULL) ||
+        ((node->type != XML_ELEMENT_NODE) &&
+         (node->type != XML_DOCUMENT_NODE) &&
+         (node->type != XML_HTML_DOCUMENT_NODE)))
+	return;
+    if (node->type == XML_ELEMENT_NODE)
+        node->psvi = NULL;
+
+    cur = node->children;
+    while (cur != NULL) {
+	if (cur->type == XML_ELEMENT_NODE) {
+	    cur->psvi = NULL;
+	    if (cur->children != NULL) {
+		cur = cur->children;
+		continue;
+	    }
+	}
+	if (cur->next != NULL) {
+	    cur = cur->next;
+	    continue;
+	}
+	do {
+	    cur = cur->parent;
+	    if (cur == NULL)
+		break;
+	    if (cur == node) {
+		cur = NULL;
+		break;
+	    }
+	    if (cur->next != NULL) {
+		cur = cur->next;
+		break;
+	    }
+	} while (cur != NULL);
+    }
+    return;
+}
 /************************************************************************
  * 									*
  * 			Validation interfaces				*
@@ -10808,6 +11015,11 @@
 
     ret = xmlRelaxNGValidateDocument(ctxt, doc);
     /*
+     * Remove all left PSVI
+     */
+    xmlRelaxNGCleanPSVI((xmlNodePtr) doc);
+
+    /*
      * TODO: build error codes
      */
     if (ret == -1)
diff --git a/threads.c b/threads.c
index 2223e8a..1eeac0e 100644
--- a/threads.c
+++ b/threads.c
@@ -26,9 +26,7 @@
 #endif
 #ifdef HAVE_PTHREAD_H
 #include <pthread.h>
-#endif
-
-#ifdef HAVE_WIN32_THREADS
+#elif defined HAVE_WIN32_THREADS
 #include <windows.h>
 #ifndef HAVE_COMPILER_TLS
 #include <process.h>
@@ -412,7 +410,7 @@
     if (tok->held == 0) {
         if (tok->waiters)
             pthread_cond_signal(&tok->cv);
-        tok->tid = 0;
+        memset(&tok->tid, 0, sizeof(tok->tid));
     }
     pthread_mutex_unlock(&tok->lock);
 #elif defined HAVE_WIN32_THREADS
@@ -441,7 +439,8 @@
     /* Make sure the global init lock is initialized and then lock it. */
 #ifdef HAVE_PTHREAD_H
     /* The mutex is statically initialized, so we just lock it. */
-    pthread_mutex_lock(&global_init_lock);
+    if (pthread_mutex_lock)
+        pthread_mutex_lock(&global_init_lock);
 #elif defined HAVE_WIN32_THREADS
     LPCRITICAL_SECTION cs;
 
@@ -510,7 +509,8 @@
 __xmlGlobalInitMutexUnlock(void)
 {
 #ifdef HAVE_PTHREAD_H
-    pthread_mutex_unlock(&global_init_lock);
+    if (pthread_mutex_unlock)
+        pthread_mutex_unlock(&global_init_lock);
 #elif defined HAVE_WIN32_THREADS
     if (global_init_lock != NULL) {
 	LeaveCriticalSection(global_init_lock);
@@ -529,7 +529,8 @@
 void
 __xmlGlobalInitMutexDestroy(void)
 {
-#if defined HAVE_WIN32_THREADS
+#ifdef HAVE_PTHREAD_H
+#elif defined HAVE_WIN32_THREADS
     if (global_init_lock != NULL) {
         DeleteCriticalSection(global_init_lock);
         free(global_init_lock);
@@ -593,8 +594,8 @@
 }
 #endif /* LIBXML_THREAD_ENABLED */
 
-
-#ifdef HAVE_WIN32_THREADS
+#ifdef HAVE_PTHREAD_H
+#elif defined HAVE_WIN32_THREADS
 #if !defined(HAVE_COMPILER_TLS)
 #if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
 typedef struct _xmlGlobalStateCleanupHelperParams {
@@ -758,6 +759,8 @@
  * xmlGetThreadId:
  *
  * xmlGetThreadId() find the current thread ID number
+ * Note that this is likely to be broken on some platforms using pthreads
+ * as the specification doesn't mandate pthread_t to be an integer type
  *
  * Returns the current thread ID number
  */
@@ -765,9 +768,15 @@
 xmlGetThreadId(void)
 {
 #ifdef HAVE_PTHREAD_H
+    pthread_t id;
+    int ret;
+
     if (libxml_is_threaded == 0)
         return (0);
-    return ((int) pthread_self());
+    id = pthread_self();
+    /* horrible but preserves compat, see warning above */
+    memcpy(&ret, &id, sizeof(ret));
+    return (ret);
 #elif defined HAVE_WIN32_THREADS
     return GetCurrentThreadId();
 #elif defined HAVE_BEOS_THREADS
@@ -803,7 +812,7 @@
     xmlGenericError(xmlGenericErrorContext, "xmlIsMainThread()\n");
 #endif
 #ifdef HAVE_PTHREAD_H
-    return (mainthread == pthread_self());
+    return (pthread_equal(mainthread,pthread_self()));
 #elif defined HAVE_WIN32_THREADS
     return (mainthread == GetCurrentThreadId());
 #elif defined HAVE_BEOS_THREADS
@@ -852,12 +861,6 @@
 void
 xmlInitThreads(void)
 {
-#ifdef DEBUG_THREADS
-    xmlGenericError(xmlGenericErrorContext, "xmlInitThreads()\n");
-#endif
-#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
-    InitializeCriticalSection(&cleanup_helpers_cs);
-#endif
 #ifdef HAVE_PTHREAD_H
     if (libxml_is_threaded == -1) {
         if ((pthread_once != NULL) &&
@@ -884,6 +887,8 @@
             libxml_is_threaded = 0;
         }
     }
+#elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
+    InitializeCriticalSection(&cleanup_helpers_cs);
 #endif
 }
 
@@ -892,6 +897,14 @@
  *
  * xmlCleanupThreads() is used to to cleanup all the thread related
  * data of the libxml2 library once processing has ended.
+ *
+ * WARNING: if your application is multithreaded or has plugin support
+ *          calling this may crash the application if another thread or
+ *          a plugin is still using libxml2. It's sometimes very hard to
+ *          guess if libxml2 is in use in the application, some libraries
+ *          or plugins may use it without notice. In case of doubt abstain
+ *          from calling this function or do it just before calling exit()
+ *          to avoid leak reports from valgrind !
  */
 void
 xmlCleanupThreads(void)
@@ -899,7 +912,10 @@
 #ifdef DEBUG_THREADS
     xmlGenericError(xmlGenericErrorContext, "xmlCleanupThreads()\n");
 #endif
-#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
+#ifdef HAVE_PTHREAD_H
+    if ((libxml_is_threaded)  && (pthread_key_delete != NULL))
+        pthread_key_delete(globalkey);
+#elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
     if (globalkey != TLS_OUT_OF_INDEXES) {
         xmlGlobalStateCleanupHelperParams *p;
 
@@ -918,9 +934,6 @@
         globalkey = TLS_OUT_OF_INDEXES;
     }
     DeleteCriticalSection(&cleanup_helpers_cs);
-#elif defined HAVE_PTHREAD_H
-    if ((libxml_is_threaded)  && (pthread_key_delete != NULL))
-        pthread_key_delete(globalkey);
 #endif
 }
 
@@ -941,9 +954,7 @@
 #ifdef HAVE_PTHREAD_H
     (void) pthread_key_create(&globalkey, xmlFreeGlobalState);
     mainthread = pthread_self();
-#endif
-
-#if defined(HAVE_WIN32_THREADS)
+#elif defined(HAVE_WIN32_THREADS)
     if (!run_once.done) {
         if (InterlockedIncrement(&run_once.control) == 1) {
 #if !defined(HAVE_COMPILER_TLS)
@@ -958,9 +969,7 @@
                 Sleep(0);
         }
     }
-#endif
-
-#ifdef HAVE_BEOS_THREADS
+#elif defined HAVE_BEOS_THREADS
     if (atomic_add(&run_once_init, 1) == 0) {
         globalkey = tls_allocate();
         tls_set(globalkey, NULL);
@@ -982,7 +991,8 @@
  *
  * Returns TRUE always
  */
-#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
+#ifdef HAVE_PTHREAD_H
+#elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
 #if defined(LIBXML_STATIC_FOR_DLL)
 BOOL XMLCALL
 xmlDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
diff --git a/tree.c b/tree.c
index 8e393da..a2fdcbf 100644
--- a/tree.c
+++ b/tree.c
@@ -49,7 +49,8 @@
  *									*
  ************************************************************************/
 
-xmlNsPtr xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns);
+static xmlNsPtr
+xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns);
 
 static xmlChar* xmlGetPropNodeValueInternal(xmlAttrPtr prop);
 
@@ -720,8 +721,19 @@
     if ((node != NULL) && (node->type != XML_ELEMENT_NODE))
 	return(NULL);
 
-    if ((prefix != NULL) && (xmlStrEqual(prefix, BAD_CAST "xml")))
-	return(NULL);
+    if ((prefix != NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))) {
+        /* xml namespace is predefined, no need to add it */
+        if (xmlStrEqual(href, XML_XML_NAMESPACE))
+            return(NULL);
+
+        /*
+         * Problem, this is an attempt to bind xml prefix to a wrong
+         * namespace, which breaks
+         * Namespace constraint: Reserved Prefixes and Namespace Names
+         * from XML namespace. But documents authors may not care in
+         * their context so let's proceed.
+         */
+    }
 
     /*
      * Allocate a new Namespace and fill the fields.
@@ -1420,9 +1432,9 @@
 	    node = xmlNewDocTextLen(doc, q, cur - q);
 	    if (node == NULL) return(ret);
 	    if (last == NULL) {
-		last = ret = node;
+		ret = node;
 	    } else {
-		last = xmlAddNextSibling(last, node);
+		xmlAddNextSibling(last, node);
 	    }
 	}
     }
@@ -1589,8 +1601,6 @@
 			last = xmlAddNextSibling(last, node);
 		    }
 		}
-
-		charval = 0;
 	    }
 	} else
 	    cur++;
@@ -1800,7 +1810,7 @@
     cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
     if (cur == NULL) {
         if ((eatname == 1) &&
-	    ((node->doc == NULL) ||
+	    ((node == NULL) || (node->doc == NULL) ||
 	     (!(xmlDictOwns(node->doc->dict, name)))))
             xmlFree((xmlChar *) name);
         xmlTreeErrMemory("building attribute");
@@ -1860,7 +1870,8 @@
         }
     }
 
-    if (xmlIsID((node == NULL) ? NULL : node->doc, node, cur) == 1)
+    if ((value != NULL) && (node != NULL) &&
+        (xmlIsID(node->doc, node, cur) == 1))
         xmlAddID(NULL, node->doc, value, cur);
 
     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
@@ -3103,6 +3114,14 @@
 	return(NULL);
     }
 
+    if (cur == elem) {
+#ifdef DEBUG_TREE
+        xmlGenericError(xmlGenericErrorContext,
+		"xmlAddSibling : cur == elem\n");
+#endif
+	return(NULL);
+    }
+
     /*
      * Constant time is we can rely on the ->parent->last to find
      * the last sibling.
@@ -3519,7 +3538,7 @@
     while (node != NULL) {
         if (node->type == XML_ELEMENT_NODE)
             return(node);
-        node = node->next;
+        node = node->prev;
     }
     return(NULL);
 }
@@ -3713,6 +3732,8 @@
  * @cur:  the node
  *
  * Unlink a node from it's current context, the node is not freed
+ * If one need to free the node, use xmlNodeFree() routine after the
+ * unlink.
  */
 void
 xmlUnlinkNode(xmlNodePtr cur) {
@@ -4160,7 +4181,8 @@
 
     if (!extended)
 	goto out;
-    if ((node->type == XML_ELEMENT_NODE) && (node->nsDef != NULL))
+    if (((node->type == XML_ELEMENT_NODE) ||
+         (node->type == XML_XINCLUDE_START)) && (node->nsDef != NULL))
         ret->nsDef = xmlCopyNamespaceList(node->nsDef);
 
     if (node->ns != NULL) {
@@ -4179,6 +4201,8 @@
 
 		while (root->parent != NULL) root = root->parent;
 		ret->ns = xmlNewNs(root, ns->href, ns->prefix);
+		} else {
+			ret->ns = xmlNewReconciliedNs(doc, ret, node->ns);
 	    }
 	} else {
 	    /*
@@ -4187,7 +4211,8 @@
 	    ret->ns = ns;
 	}
     }
-    if ((node->type == XML_ELEMENT_NODE) && (node->properties != NULL))
+    if (((node->type == XML_ELEMENT_NODE) ||
+         (node->type == XML_XINCLUDE_START)) && (node->properties != NULL))
         ret->properties = xmlCopyPropList(ret, node->properties);
     if (node->type == XML_ENTITY_REF_NODE) {
 	if ((doc == NULL) || (node->doc != doc)) {
@@ -5046,7 +5071,7 @@
 void
 xmlNodeSetBase(xmlNodePtr cur, const xmlChar* uri) {
     xmlNsPtr ns;
-    const xmlChar* fixed;
+    xmlChar* fixed;
 
     if (cur == NULL) return;
     switch(cur->type) {
@@ -5093,7 +5118,7 @@
     fixed = xmlPathToURI(uri);
     if (fixed != NULL) {
 	xmlSetNsProp(cur, ns, BAD_CAST "base", fixed);
-	xmlFree((xmlChar *)fixed);
+	xmlFree(fixed);
     } else {
 	xmlSetNsProp(cur, ns, BAD_CAST "base", uri);
     }
@@ -5112,7 +5137,7 @@
  * and
  * 5.1.2. Base URI from the Encapsulating Entity
  * However it does not return the document base (5.1.3), use
- * xmlDocumentGetBase() for this
+ * doc->URL in this case
  *
  * Returns a pointer to the base URL, or NULL if not found
  *     It's up to the caller to free the memory with xmlFree().
@@ -6045,7 +6070,7 @@
  * @tree or on one of its ancestors then a new prefix is generated.
  * Returns the (new) namespace definition or NULL in case of error
  */
-xmlNsPtr
+static xmlNsPtr
 xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) {
     xmlNsPtr def;
     xmlChar prefix[50];
@@ -7061,11 +7086,13 @@
     if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
     if (len + buf->use < buf->size) return(0);
 
-/*
- * Windows has a BIG problem on realloc timing, so we try to double
- * the buffer size (if that's enough) (bug 146697)
- */
-#ifdef WIN32
+    /*
+     * Windows has a BIG problem on realloc timing, so we try to double
+     * the buffer size (if that's enough) (bug 146697)
+     * Apparently BSD too, and it's probably best for linux too
+     * On an embedded system this may be something to change
+     */
+#if 1
     if (buf->size > len)
         size = buf->size * 2;
     else
@@ -7765,8 +7792,11 @@
 	}
     }
     /* Create. */
-    ns->next = xmlNewNs(NULL, nsName, prefix);
-    return (ns->next);
+    if (ns != NULL) {
+        ns->next = xmlNewNs(NULL, nsName, prefix);
+        return (ns->next);
+    }
+    return(NULL);
 }
 
 /*
diff --git a/trio.c b/trio.c
index 3fac2e6..b116ccc 100644
--- a/trio.c
+++ b/trio.c
@@ -1,6 +1,6 @@
 /*************************************************************************
  *
- * $Id: trio.c 3600 2007-04-17 12:44:58Z veillard $
+ * $Id$
  *
  * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg.
  *
@@ -733,7 +733,7 @@
  *
  *************************************************************************/
 
-static TRIO_CONST char rcsid[] = "@(#)$Id: trio.c 3600 2007-04-17 12:44:58Z veillard $";
+static TRIO_CONST char rcsid[] = "@(#)$Id$";
 
 /*
  * Need this to workaround a parser bug in HP C/iX compiler that fails
diff --git a/trio.h b/trio.h
index d998f35..eab1b6d 100644
--- a/trio.h
+++ b/trio.h
@@ -1,6 +1,6 @@
 /*************************************************************************
  *
- * $Id: trio.h 1886 2003-04-03 15:28:28Z veillard $
+ * $Id$
  *
  * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg.
  *
@@ -29,7 +29,7 @@
  * HAVE_CONFIG_H as a compiler option themselves.
  */
 #if defined(HAVE_CONFIG_H)
-# include <config.h>
+# include "config.h"
 #endif
 
 #include "triodef.h"
diff --git a/triodef.h b/triodef.h
index 9ab3af1..fa89416 100644
--- a/triodef.h
+++ b/triodef.h
@@ -1,6 +1,6 @@
 /*************************************************************************
  *
- * $Id: triodef.h 3473 2006-05-31 13:35:28Z veillard $
+ * $Id$
  *
  * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
  *
diff --git a/trionan.c b/trionan.c
index e160370..95baae1 100644
--- a/trionan.c
+++ b/trionan.c
@@ -1,6 +1,6 @@
 /*************************************************************************
  *
- * $Id: trionan.c 3790 2008-09-01 13:08:57Z veillard $
+ * $Id$
  *
  * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
  *
@@ -112,7 +112,7 @@
  * Constants
  */
 
-static TRIO_CONST char rcsid[] = "@(#)$Id: trionan.c 3790 2008-09-01 13:08:57Z veillard $";
+static TRIO_CONST char rcsid[] = "@(#)$Id$";
 
 #if defined(USE_IEEE_754)
 
diff --git a/trionan.h b/trionan.h
index 92de0fd..c5de32b 100644
--- a/trionan.h
+++ b/trionan.h
@@ -1,6 +1,6 @@
 /*************************************************************************
  *
- * $Id: trionan.h 2026 2003-08-06 04:43:55Z wbrack $
+ * $Id$
  *
  * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
  *
diff --git a/triop.h b/triop.h
index a062c96..8462c56 100644
--- a/triop.h
+++ b/triop.h
@@ -1,6 +1,6 @@
 /*************************************************************************
  *
- * $Id: triop.h 1886 2003-04-03 15:28:28Z veillard $
+ * $Id$
  *
  * Copyright (C) 2000 Bjorn Reese and Daniel Stenberg.
  *
diff --git a/triostr.c b/triostr.c
index dc5592c..30d13ac 100644
--- a/triostr.c
+++ b/triostr.c
@@ -1,6 +1,6 @@
 /*************************************************************************
  *
- * $Id: triostr.c 3600 2007-04-17 12:44:58Z veillard $
+ * $Id$
  *
  * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
  *
@@ -101,7 +101,7 @@
  */
 
 #if !defined(TRIO_MINIMAL)
-static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c 3600 2007-04-17 12:44:58Z veillard $";
+static TRIO_CONST char rcsid[] = "@(#)$Id$";
 #endif
 
 /*************************************************************************
diff --git a/triostr.h b/triostr.h
index 6b8d30f..27f4ace 100644
--- a/triostr.h
+++ b/triostr.h
@@ -1,6 +1,6 @@
 /*************************************************************************
  *
- * $Id: triostr.h 3600 2007-04-17 12:44:58Z veillard $
+ * $Id$
  *
  * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
  *
diff --git a/uri.c b/uri.c
index 28401c8..1ae5768 100644
--- a/uri.c
+++ b/uri.c
@@ -127,7 +127,7 @@
       (((*(p) == '!')) || ((*(p) == '$')) || ((*(p) == '&')) ||		\
        ((*(p) == '(')) || ((*(p) == ')')) || ((*(p) == '*')) ||		\
        ((*(p) == '+')) || ((*(p) == ',')) || ((*(p) == ';')) ||		\
-       ((*(p) == '=')))
+       ((*(p) == '=')) || ((*(p) == '\'')))
 
 /*
  *    gen-delims    = ":" / "/" / "?" / "#" / "[" / "]" / "@"
@@ -558,10 +558,14 @@
     }
     if (uri != NULL) {
 	if (uri->path != NULL) xmlFree(uri->path);
-	if (uri->cleanup & 2)
-	    uri->path = STRNDUP(*str, cur - *str);
-	else
-	    uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+        if (*str != cur) {
+            if (uri->cleanup & 2)
+                uri->path = STRNDUP(*str, cur - *str);
+            else
+                uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+        } else {
+            uri->path = NULL;
+        }
     }
     *str = cur;
     return (0);
@@ -600,10 +604,14 @@
     }
     if (uri != NULL) {
 	if (uri->path != NULL) xmlFree(uri->path);
-	if (uri->cleanup & 2)
-	    uri->path = STRNDUP(*str, cur - *str);
-	else
-	    uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+        if (cur != *str) {
+            if (uri->cleanup & 2)
+                uri->path = STRNDUP(*str, cur - *str);
+            else
+                uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+        } else {
+            uri->path = NULL;
+        }
     }
     *str = cur;
     return (0);
@@ -638,10 +646,14 @@
     }
     if (uri != NULL) {
 	if (uri->path != NULL) xmlFree(uri->path);
-	if (uri->cleanup & 2)
-	    uri->path = STRNDUP(*str, cur - *str);
-	else
-	    uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+        if (cur != *str) {
+            if (uri->cleanup & 2)
+                uri->path = STRNDUP(*str, cur - *str);
+            else
+                uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+        } else {
+            uri->path = NULL;
+        }
     }
     *str = cur;
     return (0);
@@ -676,10 +688,14 @@
     }
     if (uri != NULL) {
 	if (uri->path != NULL) xmlFree(uri->path);
-	if (uri->cleanup & 2)
-	    uri->path = STRNDUP(*str, cur - *str);
-	else
-	    uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+        if (cur != *str) {
+            if (uri->cleanup & 2)
+                uri->path = STRNDUP(*str, cur - *str);
+            else
+                uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+        } else {
+            uri->path = NULL;
+        }
     }
     *str = cur;
     return (0);
@@ -1373,7 +1389,7 @@
 		    }
 		    ret = temp;
     }
-    ret[len++] = 0;
+    ret[len] = 0;
     return(ret);
 }
 
diff --git a/valid.c b/valid.c
index ea47142..5de491d 100644
--- a/valid.c
+++ b/valid.c
@@ -637,8 +637,6 @@
    else if ((doc->intSubset == NULL) &&				\
 	    (doc->extSubset == NULL)) return(0)
 
-xmlAttributePtr xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem);
-
 #ifdef LIBXML_REGEXP_ENABLED
 
 /************************************************************************
@@ -1833,53 +1831,6 @@
 
 #ifdef LIBXML_VALID_ENABLED
 /**
- * xmlScanAttributeDeclCallback:
- * @attr:  the attribute decl
- * @list:  the list to update
- *
- * Callback called by xmlScanAttributeDecl when a new attribute
- * has to be entered in the list.
- */
-static void
-xmlScanAttributeDeclCallback(xmlAttributePtr attr, xmlAttributePtr *list,
-	                     const xmlChar* name ATTRIBUTE_UNUSED) {
-    attr->nexth = *list;
-    *list = attr;
-}
-
-/**
- * xmlScanAttributeDecl:
- * @dtd:  pointer to the DTD
- * @elem:  the element name
- *
- * When inserting a new element scan the DtD for existing attributes
- * for that element and initialize the Attribute chain
- *
- * Returns the pointer to the first attribute decl in the chain,
- *         possibly NULL.
- */
-xmlAttributePtr
-xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem) {
-    xmlAttributePtr ret = NULL;
-    xmlAttributeTablePtr table;
-
-    if (dtd == NULL) {
-	return(NULL);
-    }
-    if (elem == NULL) {
-	return(NULL);
-    }
-    table = (xmlAttributeTablePtr) dtd->attributes;
-    if (table == NULL) 
-        return(NULL);
-
-    /* WRONG !!! */
-    xmlHashScan3(table, NULL, NULL, elem,
-	        (xmlHashScanner) xmlScanAttributeDeclCallback, &ret);
-    return(ret);
-}
-
-/**
  * xmlScanIDAttributeDecl:
  * @ctxt:  the validation context
  * @elem:  the element name
@@ -2728,7 +2679,8 @@
         (!strcmp((char *) attr->ns->prefix, "xml")))
 	return(1);
     if (doc == NULL) return(0);
-    if ((doc->intSubset == NULL) && (doc->extSubset == NULL)) {
+    if ((doc->intSubset == NULL) && (doc->extSubset == NULL) &&
+        (doc->type != XML_HTML_DOCUMENT_NODE)) {
 	return(0);
     } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
         if ((xmlStrEqual(BAD_CAST "id", attr->name)) ||
@@ -3399,7 +3351,8 @@
 xmlValidateNotationUse(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
                        const xmlChar *notationName) {
     xmlNotationPtr notaDecl;
-    if ((doc == NULL) || (doc->intSubset == NULL)) return(-1);
+    if ((doc == NULL) || (doc->intSubset == NULL) ||
+        (notationName == NULL)) return(-1);
 
     notaDecl = xmlGetDtdNotationDesc(doc->intSubset, notationName);
     if ((notaDecl == NULL) && (doc->extSubset != NULL))
@@ -4100,13 +4053,10 @@
     if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
 	xmlChar fn[50];
 	xmlChar *fullname;
-	
+
 	fullname = xmlBuildQName(elem->name, elem->ns->prefix, fn, 50);
 	if (fullname == NULL)
 	    return(NULL);
-	attrDecl = xmlGetDtdAttrDesc(doc->intSubset, fullname, name);
-	if ((attrDecl == NULL) && (doc->extSubset != NULL))
-	    attrDecl = xmlGetDtdAttrDesc(doc->extSubset, fullname, name);
 	if ((fullname != fn) && (fullname != elem->name))
 	    xmlFree(fullname);
     }
@@ -4305,15 +4255,15 @@
 		while (next != NULL) {
 		    if (next->type == XML_ELEMENT_CONTENT_ELEMENT) {
 		        if ((xmlStrEqual(next->name, name)) &&
-			    (xmlStrEqual(next->prefix, cur->prefix))) {
-			    if (cur->prefix == NULL) {
+			    (xmlStrEqual(next->prefix, cur->c1->prefix))) {
+			    if (cur->c1->prefix == NULL) {
 				xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_CONTENT_ERROR,
 		   "Definition of %s has duplicate references of %s\n",
 				       elem->name, name, NULL);
 			    } else {
 				xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_CONTENT_ERROR,
 		   "Definition of %s has duplicate references of %s:%s\n",
-				       elem->name, cur->prefix, name);
+				       elem->name, cur->c1->prefix, name);
 			    }
 			    ret = 0;
 			}
@@ -4322,15 +4272,15 @@
 		    if (next->c1 == NULL) break;
 		    if (next->c1->type != XML_ELEMENT_CONTENT_ELEMENT) break;
 		    if ((xmlStrEqual(next->c1->name, name)) &&
-		        (xmlStrEqual(next->c1->prefix, cur->prefix))) {
-			if (cur->prefix == NULL) {
+		        (xmlStrEqual(next->c1->prefix, cur->c1->prefix))) {
+			if (cur->c1->prefix == NULL) {
 			    xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_CONTENT_ERROR,
 	       "Definition of %s has duplicate references to %s\n",
 				   elem->name, name, NULL);
 			} else {
 			    xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_CONTENT_ERROR,
 	       "Definition of %s has duplicate references to %s:%s\n",
-				   elem->name, cur->prefix, name);
+				   elem->name, cur->c1->prefix, name);
 			}
 			ret = 0;
 		    }
@@ -6609,6 +6559,7 @@
 int
 xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
     xmlRefTablePtr table;
+    unsigned int save;
 
     if (ctxt == NULL)
         return(0);
@@ -6618,6 +6569,10 @@
 	return(0);
     }
 
+    /* trick to get correct line id report */
+    save = ctxt->finishDtd;
+    ctxt->finishDtd = 0;
+
     /*
      * Check all the NOTATION/NOTATIONS attributes
      */
@@ -6631,6 +6586,8 @@
     ctxt->doc = doc;
     ctxt->valid = 1;
     xmlHashScan(table, (xmlHashScanner) xmlValidateCheckRefCallback, ctxt);
+
+    ctxt->finishDtd = save;
     return(ctxt->valid);
 }
 
diff --git a/xinclude.c b/xinclude.c
index ae449f8..2916ffa 100644
--- a/xinclude.c
+++ b/xinclude.c
@@ -438,9 +438,9 @@
      * try to ensure that new documents included are actually
      * built with the same dictionary as the including document.
      */
-    if ((ctxt->doc != NULL) && (ctxt->doc->dict != NULL) &&
-        (pctxt->dict != NULL)) {
-	xmlDictFree(pctxt->dict);
+    if ((ctxt->doc != NULL) && (ctxt->doc->dict != NULL)) {
+       if (pctxt->dict != NULL)
+            xmlDictFree(pctxt->dict);
 	pctxt->dict = ctxt->doc->dict;
 	xmlDictReference(pctxt->dict);
     }
@@ -798,6 +798,10 @@
  *									*
  ************************************************************************/
 
+static xmlNodePtr
+xmlXIncludeCopyNodeList(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
+	                xmlDocPtr source, xmlNodePtr elem);
+
 /**
  * xmlXIncludeCopyNode:
  * @ctxt:  the XInclude context
@@ -818,7 +822,10 @@
 	return(NULL);
     if (elem->type == XML_DTD_NODE)
 	return(NULL);
-    result = xmlDocCopyNode(elem, target, 1);
+    if (elem->type == XML_DOCUMENT_NODE)
+	result = xmlXIncludeCopyNodeList(ctxt, target, source, elem->children);
+    else
+        result = xmlDocCopyNode(elem, target, 1);
     return(result);
 }
 
@@ -967,7 +974,6 @@
 		    if ((cur == start) && (index1 > 1)) {
 			content += (index1 - 1);
 			len -= (index1 - 1);
-			index1 = 0;
 		    } else {
 			len = index2;
 		    }
@@ -2423,7 +2429,42 @@
     ctxt->parseFlags = flags;
     return(0);
 }
- 
+
+/**
+ * xmlXIncludeProcessTreeFlagsData:
+ * @tree: an XML node
+ * @flags: a set of xmlParserOption used for parsing XML includes
+ * @data: application data that will be passed to the parser context
+ *        in the _private field of the parser context(s)
+ *
+ * Implement the XInclude substitution on the XML node @tree
+ *
+ * Returns 0 if no substitution were done, -1 if some processing failed
+ *    or the number of substitutions done.
+ */
+
+int
+xmlXIncludeProcessTreeFlagsData(xmlNodePtr tree, int flags, void *data) {
+    xmlXIncludeCtxtPtr ctxt;
+    int ret = 0;
+
+    if ((tree == NULL) || (tree->doc == NULL))
+        return(-1);
+
+    ctxt = xmlXIncludeNewContext(tree->doc);
+    if (ctxt == NULL)
+        return(-1);
+    ctxt->_private = data;
+    ctxt->base = xmlStrdup((xmlChar *)tree->doc->URL);
+    xmlXIncludeSetFlags(ctxt, flags);
+    ret = xmlXIncludeDoProcess(ctxt, tree->doc, tree);
+    if ((ret >= 0) && (ctxt->nbErrors > 0))
+        ret = -1;
+
+    xmlXIncludeFreeContext(ctxt);
+    return(ret);
+}
+
 /**
  * xmlXIncludeProcessFlagsData:
  * @doc: an XML document
@@ -2438,27 +2479,14 @@
  */
 int
 xmlXIncludeProcessFlagsData(xmlDocPtr doc, int flags, void *data) {
-    xmlXIncludeCtxtPtr ctxt;
     xmlNodePtr tree;
-    int ret = 0;
 
     if (doc == NULL)
 	return(-1);
     tree = xmlDocGetRootElement(doc);
     if (tree == NULL)
 	return(-1);
-    ctxt = xmlXIncludeNewContext(doc);
-    if (ctxt == NULL)
-	return(-1);
-    ctxt->_private = data;
-    ctxt->base = xmlStrdup((xmlChar *)doc->URL);
-    xmlXIncludeSetFlags(ctxt, flags);
-    ret = xmlXIncludeDoProcess(ctxt, doc, tree);
-    if ((ret >= 0) && (ctxt->nbErrors > 0))
-	ret = -1;
-
-    xmlXIncludeFreeContext(ctxt);
-    return(ret);
+    return(xmlXIncludeProcessTreeFlagsData(tree, flags, data));
 }
 
 /**
diff --git a/xmlIO.c b/xmlIO.c
index d4dc364..73a995d 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -35,6 +35,9 @@
 #ifdef HAVE_ZLIB_H
 #include <zlib.h>
 #endif
+#ifdef HAVE_LZMA_H
+#include <lzma.h>
+#endif
 
 #if defined(WIN32) || defined(_WIN32)
 #include <windows.h>
@@ -142,7 +145,7 @@
 
 /************************************************************************
  *									*
- * 		Tree memory error handler				*
+ *		Tree memory error handler				*
  *									*
  ************************************************************************/
 
@@ -425,7 +428,7 @@
     idx = 0;
     if (code >= XML_IO_UNKNOWN) idx = code - XML_IO_UNKNOWN;
     if (idx >= (sizeof(IOerr) / sizeof(IOerr[0]))) idx = 0;
-    
+
     __xmlSimpleError(domain, code, NULL, IOerr[idx], extra);
 }
 
@@ -477,12 +480,12 @@
                     XML_IO_LOAD_ERROR, level, NULL, 0,
 		    filename, NULL, NULL, 0, 0,
 		    msg, filename);
-                    
+
 }
 
 /************************************************************************
  *									*
- * 		Tree memory error handler				*
+ *		Tree memory error handler				*
  *									*
  ************************************************************************/
 /**
@@ -504,7 +507,7 @@
  * xmlCleanupInputCallbacks:
  *
  * clears the entire input callback table. this includes the
- * compiled-in I/O. 
+ * compiled-in I/O.
  */
 void
 xmlCleanupInputCallbacks(void)
@@ -529,7 +532,7 @@
  * xmlPopInputCallbacks:
  *
  * Clear the top input callback from the input stack. this includes the
- * compiled-in I/O. 
+ * compiled-in I/O.
  *
  * Returns the number of input callback registered or -1 in case of error.
  */
@@ -541,7 +544,7 @@
 
     if (xmlInputCallbackNr <= 0)
         return(-1);
-        
+
     xmlInputCallbackNr--;
     xmlInputCallbackTable[xmlInputCallbackNr].matchcallback = NULL;
     xmlInputCallbackTable[xmlInputCallbackNr].opencallback = NULL;
@@ -556,7 +559,7 @@
  * xmlCleanupOutputCallbacks:
  *
  * clears the entire output callback table. this includes the
- * compiled-in I/O callbacks. 
+ * compiled-in I/O callbacks.
  */
 void
 xmlCleanupOutputCallbacks(void)
@@ -613,6 +616,34 @@
     return fd;
 }
 
+#ifdef HAVE_ZLIB_H
+static gzFile
+xmlWrapGzOpenUtf8(const char *path, const char *mode)
+{
+    gzFile fd;
+    wchar_t *wPath;
+
+    fd = gzopen (path, mode);
+    if (fd)
+        return fd;
+
+    wPath = __xmlIOWin32UTF8ToWChar(path);
+    if(wPath)
+    {
+	int d, m = (strstr(mode, "r") ? O_RDONLY : O_RDWR);
+#ifdef _O_BINARY
+        m |= (strstr(mode, "b") ? _O_BINARY : 0);
+#endif
+	d = _wopen(wPath, m);
+	if (d >= 0)
+	    fd = gzdopen(d, mode);
+        xmlFree(wPath);
+    }
+
+    return fd;
+}
+#endif
+
 /**
  *  xmlWrapStatUtf8:
  * @path:  the path in utf-8 encoding
@@ -679,7 +710,10 @@
 static xmlWrapStatFunc xmlWrapStat = xmlWrapStatNative;
 typedef FILE* (* xmlWrapOpenFunc)(const char *f,int mode);
 static xmlWrapOpenFunc xmlWrapOpen = xmlWrapOpenNative;
-
+#ifdef HAVE_ZLIB_H
+typedef gzFile (* xmlWrapGzOpenFunc) (const char *f, const char *mode);
+static xmlWrapGzOpenFunc xmlWrapGzOpen = gzopen;
+#endif
 /**
  * xmlInitPlatformSpecificIo:
  *
@@ -699,9 +733,15 @@
     if(GetVersionEx(&osvi) && (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)) {
       xmlWrapStat = xmlWrapStatUtf8;
       xmlWrapOpen = xmlWrapOpenUtf8;
+#ifdef HAVE_ZLIB_H
+      xmlWrapGzOpen = xmlWrapGzOpenUtf8;
+#endif
     } else {
       xmlWrapStat = xmlWrapStatNative;
       xmlWrapOpen = xmlWrapOpenNative;
+#ifdef HAVE_ZLIB_H
+      xmlWrapGzOpen = gzopen;
+#endif
     }
 
     xmlPlatformIoInitialized = 1;
@@ -866,7 +906,7 @@
 #else
 	path = &filename[5];
 #endif
-    } else 
+    } else
 	path = filename;
 
     if (path == NULL)
@@ -941,7 +981,7 @@
 #else
 	path = &filename[7];
 #endif
-    } else 
+    } else
 	path = filename;
 
     if (path == NULL)
@@ -950,7 +990,7 @@
 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
     fd = xmlWrapOpen(path, 1);
 #else
-  	   fd = fopen(path, "wb");
+ 	   fd = fopen(path, "wb");
 #endif /* WIN32 */
 
 	 if (fd == NULL) xmlIOErr(0, path);
@@ -971,7 +1011,7 @@
 int
 xmlFileRead (void * context, char * buffer, int len) {
     int ret;
-    if ((context == NULL) || (buffer == NULL)) 
+    if ((context == NULL) || (buffer == NULL))
         return(-1);
     ret = fread(&buffer[0], 1,  len, (FILE *) context);
     if (ret < 0) xmlIOErr(0, "fread()");
@@ -993,7 +1033,7 @@
 xmlFileWrite (void * context, const char * buffer, int len) {
     int items;
 
-    if ((context == NULL) || (buffer == NULL)) 
+    if ((context == NULL) || (buffer == NULL))
         return(-1);
     items = fwrite(&buffer[0], len, 1, (FILE *) context);
     if ((items == 0) && (ferror((FILE *) context))) {
@@ -1124,7 +1164,7 @@
 #else
 	path = &filename[7];
 #endif
-    } else 
+    } else
 	path = filename;
 
     if (path == NULL)
@@ -1132,7 +1172,11 @@
     if (!xmlCheckFilename(path))
         return(NULL);
 
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+    fd = xmlWrapGzOpen(path, "rb");
+#else
     fd = gzopen(path, "rb");
+#endif
     return((void *) fd);
 }
 
@@ -1194,13 +1238,17 @@
 #else
 	path = &filename[7];
 #endif
-    } else 
+    } else
 	path = filename;
 
     if (path == NULL)
 	return(NULL);
 
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+    fd = xmlWrapGzOpen(path, mode);
+#else
     fd = gzopen(path, mode);
+#endif
     return((void *) fd);
 }
 #endif /* LIBXML_OUTPUT_ENABLED */
@@ -1261,6 +1309,125 @@
 }
 #endif /* HAVE_ZLIB_H */
 
+#ifdef HAVE_LZMA_H
+/************************************************************************
+ *									*
+ *		I/O for compressed file accesses			*
+ *									*
+ ************************************************************************/
+#include "xzlib.h"
+/**
+ * xmlXzfileMatch:
+ * @filename:  the URI for matching
+ *
+ * input from compressed file test
+ *
+ * Returns 1 if matches, 0 otherwise
+ */
+static int
+xmlXzfileMatch (const char *filename ATTRIBUTE_UNUSED) {
+    return(1);
+}
+
+/**
+ * xmlXzFileOpen_real:
+ * @filename:  the URI for matching
+ *
+ * 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
+ */
+static void *
+xmlXzfileOpen_real (const char *filename) {
+    const char *path = NULL;
+    xzFile fd;
+
+    if (!strcmp(filename, "-")) {
+        fd = __libxml2_xzdopen(dup(0), "rb");
+	return((void *) fd);
+    }
+
+    if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17)) {
+	path = &filename[16];
+    } else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
+	path = &filename[7];
+    } else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:/", 6)) {
+        /* lots of generators seems to lazy to read RFC 1738 */
+	path = &filename[5];
+    } else
+	path = filename;
+
+    if (path == NULL)
+	return(NULL);
+    if (!xmlCheckFilename(path))
+        return(NULL);
+
+    fd = __libxml2_xzopen(path, "rb");
+    return((void *) fd);
+}
+
+/**
+ * xmlXzfileOpen:
+ * @filename:  the URI for matching
+ *
+ * Wrapper around xmlXzfileOpen_real that try it with an unescaped
+ * version of @filename, if this fails fallback to @filename
+ *
+ * Returns a handler or NULL in case or failure
+ */
+static void *
+xmlXzfileOpen (const char *filename) {
+    char *unescaped;
+    void *retval;
+
+    retval = xmlXzfileOpen_real(filename);
+    if (retval == NULL) {
+	unescaped = xmlURIUnescapeString(filename, 0, NULL);
+	if (unescaped != NULL) {
+	    retval = xmlXzfileOpen_real(unescaped);
+	}
+	xmlFree(unescaped);
+    }
+
+    return retval;
+}
+
+/**
+ * xmlXzfileRead:
+ * @context:  the I/O context
+ * @buffer:  where to drop data
+ * @len:  number of bytes to write
+ *
+ * Read @len bytes to @buffer from the compressed I/O channel.
+ *
+ * Returns the number of bytes written
+ */
+static int
+xmlXzfileRead (void * context, char * buffer, int len) {
+    int ret;
+
+    ret = __libxml2_xzread((xzFile) context, &buffer[0], len);
+    if (ret < 0) xmlIOErr(0, "xzread()");
+    return(ret);
+}
+
+/**
+ * xmlXzfileClose:
+ * @context:  the I/O context
+ *
+ * Close a compressed I/O channel
+ */
+static int
+xmlXzfileClose (void * context) {
+    int ret;
+
+    ret =  (__libxml2_xzclose((xzFile) context) == LZMA_OK ) ? 0 : -1;
+    if (ret < 0) xmlIOErr(0, "xzclose()");
+    return(ret);
+}
+#endif /* HAVE_LZMA_H */
+
 #ifdef LIBXML_HTTP_ENABLED
 /************************************************************************
  *									*
@@ -1322,7 +1489,7 @@
 
     /*
     **  This is plagiarized from putLong in gzio.c (zlib source) where
-    **  the number "4" is hardcoded.  If zlib is ever patched to 
+    **  the number "4" is hardcoded.  If zlib is ever patched to
     **  support 64 bit file sizes, this code would need to be patched
     **  as well.
     */
@@ -1374,7 +1541,7 @@
  *
  * Create a memory buffer to hold the compressed XML document.  The
  * compressed document in memory will end up being identical to what
- * would be created if gzopen/gzwrite/gzclose were being used to 
+ * would be created if gzopen/gzwrite/gzclose were being used to
  * write the document to disk.  The code for the header/trailer data to
  * the compression is plagiarized from the zlib source files.
  */
@@ -1423,7 +1590,7 @@
     buff->crc = crc32( 0L, NULL, 0 );
     hdr_lgth = snprintf( (char *)buff->zbuff, buff->size,
 			"%c%c%c%c%c%c%c%c%c%c",
-			GZ_MAGIC1, GZ_MAGIC2, Z_DEFLATED, 
+			GZ_MAGIC1, GZ_MAGIC2, Z_DEFLATED,
 			0, 0, 0, 0, 0, 0, LXML_ZLIB_OS_CODE );
     buff->zctrl.next_out  = buff->zbuff + hdr_lgth;
     buff->zctrl.avail_out = buff->size - hdr_lgth;
@@ -1461,11 +1628,11 @@
     new_size = buff->size + ext_amt;
 
 #ifdef DEBUG_HTTP
-    if ( cur_used > new_size ) 
+    if ( cur_used > new_size )
 	xmlGenericError( xmlGenericErrorContext,
 			"xmlZMemBuffExtend:  %s\n%s %d bytes.\n",
 			"Buffer overwrite detected during compressed memory",
-			"buffer extension.  Overflowed by", 
+			"buffer extension.  Overflowed by",
 			(cur_used - new_size ) );
 #endif
 
@@ -1603,7 +1770,7 @@
 		    "Error flushing zlib buffers.  Error code", z_err );
 	xmlIOErr(XML_IO_WRITE, (const char *) msg);
     }
-    
+
     return ( zlgth );
 }
 #endif /* LIBXML_OUTPUT_ENABLED */
@@ -1762,7 +1929,7 @@
  *
  * Returns the number of bytes written
  */
-int 
+int
 xmlIOHTTPRead(void * context, char * buffer, int len) {
     if ((buffer == NULL) || (len < 0)) return(-1);
     return(xmlNanoHTTPRead(context, &buffer[0], len));
@@ -1782,7 +1949,7 @@
  */
 
 static int
-xmlIOHTTPWrite( void * context, const char * buffer, int len ) { 
+xmlIOHTTPWrite( void * context, const char * buffer, int len ) {
 
     xmlIOHTTPWriteCtxtPtr	ctxt = context;
 
@@ -1794,7 +1961,7 @@
 	/*  Use gzwrite or fwrite as previously setup in the open call  */
 
 #ifdef HAVE_ZLIB_H
-	if ( ctxt->compression > 0 ) 
+	if ( ctxt->compression > 0 )
 	    len = xmlZMemBuffAppend( ctxt->doc_buff, buffer, len );
 
 	else
@@ -1885,7 +2052,7 @@
     else {
 
 	http_ctxt = xmlNanoHTTPMethod( ctxt->uri, http_mthd, http_content,
-					&content_type, content_encoding, 
+					&content_type, content_encoding,
 					content_lgth );
 
 	if ( http_ctxt != NULL ) {
@@ -1904,7 +2071,7 @@
 
 	    /*
 	    **  Since either content or reply may be gzipped,
-	    **  dump them to separate files instead of the 
+	    **  dump them to separate files instead of the
 	    **  standard error context.
 	    */
 
@@ -2041,7 +2208,7 @@
  *
  * Returns the number of bytes written
  */
-int 
+int
 xmlIOFTPRead(void * context, char * buffer, int len) {
     if ((buffer == NULL) || (len < 0)) return(-1);
     return(xmlNanoFTPRead(context, &buffer[0], len));
@@ -2104,7 +2271,7 @@
 xmlRegisterOutputCallbacks(xmlOutputMatchCallback matchFunc,
 	xmlOutputOpenCallback openFunc, xmlOutputWriteCallback writeFunc,
 	xmlOutputCloseCallback closeFunc) {
-    if (xmlOutputCallbackNr >= MAX_INPUT_CALLBACK) {
+    if (xmlOutputCallbackNr >= MAX_OUTPUT_CALLBACK) {
 	return(-1);
     }
     xmlOutputCallbackTable[xmlOutputCallbackNr].matchcallback = matchFunc;
@@ -2136,6 +2303,10 @@
     xmlRegisterInputCallbacks(xmlGzfileMatch, xmlGzfileOpen,
 	                      xmlGzfileRead, xmlGzfileClose);
 #endif /* HAVE_ZLIB_H */
+#ifdef HAVE_LZMA_H
+    xmlRegisterInputCallbacks(xmlXzfileMatch, xmlXzfileOpen,
+	                      xmlXzfileRead, xmlXzfileClose);
+#endif /* HAVE_ZLIB_H */
 
 #ifdef LIBXML_HTTP_ENABLED
     xmlRegisterInputCallbacks(xmlIOHTTPMatch, xmlIOHTTPOpen,
@@ -2278,6 +2449,10 @@
 	return(NULL);
     }
 
+    /* try to avoid a performance problem with Windows realloc() */
+    if (ret->buffer->alloc == XML_BUFFER_ALLOC_EXACT)
+        ret->buffer->alloc = XML_BUFFER_ALLOC_DOUBLEIT;
+
     ret->encoder = encoder;
     if (encoder != NULL) {
         ret->conv = xmlBufferCreateSize(4000);
@@ -2289,7 +2464,7 @@
 	/*
 	 * This call is designed to initiate the encoder state
 	 */
-	xmlCharEncOutFunc(encoder, ret->conv, NULL); 
+	xmlCharEncOutFunc(encoder, ret->conv, NULL);
     } else
         ret->conv = NULL;
     ret->writecallback = NULL;
@@ -2344,7 +2519,7 @@
 	/*
 	 * This call is designed to initiate the encoder state
 	 */
-	xmlCharEncOutFunc(encoder, ret->conv, NULL); 
+	xmlCharEncOutFunc(encoder, ret->conv, NULL);
     } else
         ret->conv = NULL;
     ret->writecallback = NULL;
@@ -2469,6 +2644,9 @@
 #ifdef HAVE_ZLIB_H
 	if ((xmlInputCallbackTable[i].opencallback == xmlGzfileOpen) &&
 		(strcmp(URI, "-") != 0)) {
+#if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1230
+            ret->compressed = !gzdirect(context);
+#else
 	    if (((z_stream *)context)->avail_in > 4) {
 	        char *cptr, buff4[4];
 		cptr = (char *) ((z_stream *)context)->next_in;
@@ -2480,6 +2658,7 @@
 		    gzrewind(context);
 		}
 	    }
+#endif
 	}
 #endif
     }
@@ -2662,7 +2841,7 @@
 
 /**
  * xmlParserInputBufferCreateFile:
- * @file:  a FILE* 
+ * @file:  a FILE*
  * @enc:  the charset encoding if known
  *
  * Create a buffered parser input for the progressive parsing of a FILE *
@@ -2692,7 +2871,7 @@
 #ifdef LIBXML_OUTPUT_ENABLED
 /**
  * xmlOutputBufferCreateFile:
- * @file:  a FILE* 
+ * @file:  a FILE*
  * @encoder:  the encoding converter or NULL
  *
  * Create a buffered output for the progressive saving to a FILE *
@@ -2856,7 +3035,7 @@
  * @fd:  a file descriptor number
  * @encoder:  the encoding converter or NULL
  *
- * Create a buffered output for the progressive saving 
+ * Create a buffered output for the progressive saving
  * to a file descriptor
  *
  * Returns the new parser output or NULL
@@ -3138,7 +3317,7 @@
 	in->rawconsumed += (use - in->raw->use);
     } else {
 	nbchars = len;
-    	in->buffer->use += nbchars;
+   	in->buffer->use += nbchars;
 	buffer[nbchars] = 0;
     }
 #ifdef DEBUG_INPUT
@@ -3248,12 +3427,12 @@
 	     * second write the stuff to the I/O channel
 	     */
 	    if (out->encoder != NULL) {
-		ret = out->writecallback(out->context, 
+		ret = out->writecallback(out->context,
 				 (const char *)out->conv->content, nbchars);
 		if (ret >= 0)
 		    xmlBufferShrink(out->conv, ret);
 	    } else {
-		ret = out->writecallback(out->context, 
+		ret = out->writecallback(out->context,
 				 (const char *)out->buffer->content, nbchars);
 		if (ret >= 0)
 		    xmlBufferShrink(out->buffer, ret);
@@ -3298,9 +3477,9 @@
     const unsigned char* inend;
 
     inend = in + (*inlen);
-    
+
     while ((in < inend) && (out < outend)) {
-    	if (*in == '<') {
+   	if (*in == '<') {
 	    if (outend - out < 4) break;
 	    *out++ = '&';
 	    *out++ = 'l';
@@ -3330,7 +3509,7 @@
 	    *out++ = (unsigned char) *in;
 	}
 	++in;
-    }	
+    }
     *outlen = out - outstart;
     *inlen = in - base;
     return(0);
@@ -3440,12 +3619,12 @@
 	     * second write the stuff to the I/O channel
 	     */
 	    if (out->encoder != NULL) {
-		ret = out->writecallback(out->context, 
+		ret = out->writecallback(out->context,
 				 (const char *)out->conv->content, nbchars);
 		if (ret >= 0)
 		    xmlBufferShrink(out->conv, ret);
 	    } else {
-		ret = out->writecallback(out->context, 
+		ret = out->writecallback(out->context,
 				 (const char *)out->buffer->content, nbchars);
 		if (ret >= 0)
 		    xmlBufferShrink(out->buffer, ret);
@@ -3486,7 +3665,7 @@
 int
 xmlOutputBufferWriteString(xmlOutputBufferPtr out, const char *str) {
     int len;
-    
+
     if ((out == NULL) || (out->error)) return(-1);
     if (str == NULL)
         return(-1);
@@ -3703,9 +3882,9 @@
 #else
 	path = &URL[7];
 #endif
-    } else 
+    } else
 	path = URL;
-	
+
     return xmlCheckFilename(path);
 }
 
@@ -3893,9 +4072,9 @@
 }
 
 /************************************************************************
- * 									*
- * 		Disabling Network access				*
- * 									*
+ *									*
+ *		Disabling Network access				*
+ *									*
  ************************************************************************/
 
 /**
diff --git a/xmlcatalog.c b/xmlcatalog.c
index 6f193b1..489509f 100644
--- a/xmlcatalog.c
+++ b/xmlcatalog.c
@@ -124,7 +124,6 @@
 	    free(cmdline);
 	    continue;
 	}
-	nbargs++;
 
 	/*
 	 * Parse the argument string
@@ -138,8 +137,6 @@
 	    arg[i++] = *cur++;
 	}
 	arg[i] = 0;
-	if (i != 0) 
-	    nbargs++;
 
 	/*
 	 * Parse the arguments
diff --git a/xmllint.c b/xmllint.c
index 77c1e62..2acc7c5 100644
--- a/xmllint.c
+++ b/xmllint.c
@@ -108,15 +108,16 @@
 
 typedef enum {
     XMLLINT_RETURN_OK = 0,	/* No error */
-    XMLLINT_ERR_UNCLASS,	/* Unclassified */
-    XMLLINT_ERR_DTD,		/* Error in DTD */
-    XMLLINT_ERR_VALID,		/* Validation error */
-    XMLLINT_ERR_RDFILE,		/* CtxtReadFile error */
-    XMLLINT_ERR_SCHEMACOMP,	/* Schema compilation */
-    XMLLINT_ERR_OUT,		/* Error writing output */
-    XMLLINT_ERR_SCHEMAPAT,	/* Error in schema pattern */
-    XMLLINT_ERR_RDREGIS,	/* Error in Reader registration */
-    XMLLINT_ERR_MEM		/* Out of memory error */
+    XMLLINT_ERR_UNCLASS = 1,	/* Unclassified */
+    XMLLINT_ERR_DTD = 2,	/* Error in DTD */
+    XMLLINT_ERR_VALID = 3,	/* Validation error */
+    XMLLINT_ERR_RDFILE = 4,	/* CtxtReadFile error */
+    XMLLINT_ERR_SCHEMACOMP = 5,	/* Schema compilation */
+    XMLLINT_ERR_OUT = 6,	/* Error writing output */
+    XMLLINT_ERR_SCHEMAPAT = 7,	/* Error in schema pattern */
+    XMLLINT_ERR_RDREGIS = 8,	/* Error in Reader registration */
+    XMLLINT_ERR_MEM = 9,	/* Out of memory error */
+    XMLLINT_ERR_XPATH = 10	/* XPath evaluation error */
 } xmllintReturnCode;
 #ifdef LIBXML_DEBUG_ENABLED
 static int shell = 0;
@@ -129,6 +130,7 @@
 #endif /* LIBXML_TREE_ENABLED */
 static int recovery = 0;
 static int noent = 0;
+static int noenc = 0;
 static int noblanks = 0;
 static int noout = 0;
 static int nowrap = 0;
@@ -161,6 +163,9 @@
 static int xmlout = 0;
 #endif
 static int htmlout = 0;
+#if defined(LIBXML_HTML_ENABLED)
+static int nodefdtd = 0;
+#endif
 #ifdef LIBXML_PUSH_ENABLED
 static int push = 0;
 #endif /* LIBXML_PUSH_ENABLED */
@@ -184,6 +189,7 @@
 #endif
 #ifdef LIBXML_C14N_ENABLED
 static int canonical = 0;
+static int canonical_11 = 0;
 static int exc_canonical = 0;
 #endif
 #ifdef LIBXML_READER_ENABLED
@@ -200,6 +206,9 @@
 static xmlPatternPtr patternc = NULL;
 static xmlStreamCtxtPtr patstream = NULL;
 #endif
+#ifdef LIBXML_XPATH_ENABLED
+static const char *xpathquery = NULL;
+#endif
 static int options = XML_PARSE_COMPACT;
 static int sax = 0;
 static int oldxml10 = 0;
@@ -247,7 +256,7 @@
 
 static xmlExternalEntityLoader defaultEntityLoader = NULL;
 
-static xmlParserInputPtr 
+static xmlParserInputPtr
 xmllintExternalEntityLoader(const char *URL, const char *ID,
 			     xmlParserCtxtPtr ctxt) {
     xmlParserInputPtr ret;
@@ -305,10 +314,10 @@
 		    ctxt->sax->error = err;
 		if (load_trace) {
 		    fprintf \
-		    	(stderr,
-		    	 "Loaded URL=\"%s\" ID=\"%s\"\n",
+			(stderr,
+			 "Loaded URL=\"%s\" ID=\"%s\"\n",
 			 newURL,
-		    	 ID ? ID : "(null)");
+			 ID ? ID : "(null)");
 		}
 		xmlFree(newURL);
 		return(ret);
@@ -328,9 +337,9 @@
     return(NULL);
 }
 /************************************************************************
- * 									*
+ *									*
  * Memory allocation consumption debugging				*
- * 									*
+ *									*
  ************************************************************************/
 
 static void
@@ -391,13 +400,13 @@
     return (ret);
 }
 /************************************************************************
- * 									*
+ *									*
  * Internal timing routines to remove the necessity to have		*
  * unix-specific function calls.					*
- * 									*
+ *									*
  ************************************************************************/
 
-#ifndef HAVE_GETTIMEOFDAY 
+#ifndef HAVE_GETTIMEOFDAY
 #ifdef HAVE_SYS_TIMEB_H
 #ifdef HAVE_SYS_TIME_H
 #ifdef HAVE_FTIME
@@ -523,9 +532,9 @@
 }
 #endif
 /************************************************************************
- * 									*
- * 			HTML ouput					*
- * 									*
+ *									*
+ *			HTML ouput					*
+ *									*
  ************************************************************************/
 static char buffer[50000];
 
@@ -544,7 +553,7 @@
 /**
  * xmlHTMLPrintFileInfo:
  * @input:  an xmlParserInputPtr input
- * 
+ *
  * Displays the associated file and line informations for the current input
  */
 
@@ -568,7 +577,7 @@
 /**
  * xmlHTMLPrintFileContext:
  * @input:  an xmlParserInputPtr input
- * 
+ *
  * Displays current context within the input content for error tracking
  */
 
@@ -593,7 +602,7 @@
     n = 0;
     while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
 	len = strlen(buffer);
-        snprintf(&buffer[len], sizeof(buffer) - len, "%c", 
+        snprintf(&buffer[len], sizeof(buffer) - len, "%c",
 		    (unsigned char) *cur++);
 	n++;
     }
@@ -619,7 +628,7 @@
  * @ctx:  an XML parser context
  * @msg:  the message to display/transmit
  * @...:  extra parameters for the message display
- * 
+ *
  * Display and format an error messages, gives file, line, position and
  * extra parameters.
  */
@@ -636,7 +645,7 @@
     if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
         input = ctxt->inputTab[ctxt->inputNr - 2];
     }
-        
+
     xmlHTMLPrintFileInfo(input);
 
     xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
@@ -656,7 +665,7 @@
  * @ctx:  an XML parser context
  * @msg:  the message to display/transmit
  * @...:  extra parameters for the message display
- * 
+ *
  * Display and format a warning messages, gives file, line, position and
  * extra parameters.
  */
@@ -673,13 +682,13 @@
     if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
         input = ctxt->inputTab[ctxt->inputNr - 2];
     }
-        
+
 
     xmlHTMLPrintFileInfo(input);
-        
+
     xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
     va_start(args, msg);
-    len = strlen(buffer);    
+    len = strlen(buffer);
     vsnprintf(&buffer[len],  sizeof(buffer) - len, msg, args);
     va_end(args);
     xmlHTMLEncodeSend();
@@ -694,7 +703,7 @@
  * @ctx:  an XML parser context
  * @msg:  the message to display/transmit
  * @...:  extra parameters for the message display
- * 
+ *
  * Display and format an validity error messages, gives file,
  * line, position and extra parameters.
  */
@@ -710,7 +719,7 @@
     input = ctxt->input;
     if ((input->filename == NULL) && (ctxt->inputNr > 1))
         input = ctxt->inputTab[ctxt->inputNr - 2];
-        
+
     xmlHTMLPrintFileInfo(input);
 
     xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
@@ -731,7 +740,7 @@
  * @ctx:  an XML parser context
  * @msg:  the message to display/transmit
  * @...:  extra parameters for the message display
- * 
+ *
  * Display and format a validity warning messages, gives file, line,
  * position and extra parameters.
  */
@@ -749,10 +758,10 @@
         input = ctxt->inputTab[ctxt->inputNr - 2];
 
     xmlHTMLPrintFileInfo(input);
-        
+
     xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
     va_start(args, msg);
-    len = strlen(buffer); 
+    len = strlen(buffer);
     vsnprintf(&buffer[len],  sizeof(buffer) - len, msg, args);
     va_end(args);
     xmlHTMLEncodeSend();
@@ -763,9 +772,9 @@
 }
 
 /************************************************************************
- * 									*
- * 			Shell Interface					*
- * 									*
+ *									*
+ *			Shell Interface					*
+ *									*
  ************************************************************************/
 #ifdef LIBXML_DEBUG_ENABLED
 #ifdef LIBXML_XPATH_ENABLED
@@ -774,7 +783,7 @@
  * @prompt:  the prompt value
  *
  * Read a string
- * 
+ *
  * Returns a pointer to it or NULL on EOF the caller is expected to
  *     free the returned string.
  */
@@ -813,9 +822,9 @@
 #endif /* LIBXML_DEBUG_ENABLED */
 
 /************************************************************************
- * 									*
- * 			I/O Interfaces					*
- * 									*
+ *									*
+ *			I/O Interfaces					*
+ *									*
  ************************************************************************/
 
 static int myRead(FILE *f, char * buf, int len) {
@@ -829,7 +838,7 @@
 
 /************************************************************************
  *									*
- *		 	SAX based tests					*
+ *			SAX based tests					*
  *									*
  ************************************************************************/
 
@@ -999,7 +1008,7 @@
 	return(NULL);
     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
 
-    
+
     fprintf(stdout, "SAX.resolveEntity(");
     if (publicId != NULL)
 	fprintf(stdout, "%s", (char *)publicId);
@@ -1054,8 +1063,8 @@
 /**
  * entityDeclDebug:
  * @ctxt:  An XML parser context
- * @name:  the entity name 
- * @type:  the entity type 
+ * @name:  the entity name
+ * @type:  the entity type
  * @publicId: The public ID of the entity
  * @systemId: The system ID of the entity
  * @content: the entity value (without processing).
@@ -1084,8 +1093,8 @@
 /**
  * attributeDeclDebug:
  * @ctxt:  An XML parser context
- * @name:  the attribute name 
- * @type:  the attribute type 
+ * @name:  the attribute name
+ * @type:  the attribute type
  *
  * An attribute definition has been parsed
  */
@@ -1109,8 +1118,8 @@
 /**
  * elementDeclDebug:
  * @ctxt:  An XML parser context
- * @name:  the element name 
- * @type:  the element type 
+ * @name:  the element name
+ * @type:  the element type
  * @content: the element value (without processing).
  *
  * An element definition has been parsed
@@ -1296,7 +1305,7 @@
  * @ctxt:  An XML parser context
  * @name:  The entity name
  *
- * called when an entity reference is detected. 
+ * called when an entity reference is detected.
  */
 static void
 referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
@@ -1532,7 +1541,7 @@
     else
 	fprintf(stdout, ", '%s'", (char *) URI);
     fprintf(stdout, ", %d", nb_namespaces);
-    
+
     if (namespaces != NULL) {
         for (i = 0;i < nb_namespaces * 2;i++) {
 	    fprintf(stdout, ", xmlns");
@@ -1695,7 +1704,7 @@
 	    goto error;
 	}
 	inputPush(ctxt, inputStream);
-	
+
 	/* do the parsing */
 	xmlParseDocument(ctxt);
 
@@ -1714,9 +1723,9 @@
 }
 
 /************************************************************************
- * 									*
- * 			Stream Test processing				*
- * 									*
+ *									*
+ *			Stream Test processing				*
+ *									*
  ************************************************************************/
 #ifdef LIBXML_READER_ENABLED
 static void processNode(xmlTextReaderPtr reader) {
@@ -1733,8 +1742,8 @@
 
 	value = xmlTextReaderConstValue(reader);
 
-	
-	printf("%d %d %s %d %d", 
+
+	printf("%d %d %s %d %d",
 		xmlTextReaderDepth(reader),
 		type,
 		name,
@@ -1750,14 +1759,19 @@
     if (patternc) {
         xmlChar *path = NULL;
         int match = -1;
-	
+
 	if (type == XML_READER_TYPE_ELEMENT) {
 	    /* do the check only on element start */
 	    match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));
 
 	    if (match) {
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
 		path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
 		printf("Node %s matches pattern %s\n", path, pattern);
+#else
+                printf("Node %s matches pattern %s\n",
+                       xmlTextReaderConstName(reader), pattern);
+#endif
 	    }
 	}
 	if (patstream != NULL) {
@@ -1772,19 +1786,23 @@
                     xmlFreeStreamCtxt(patstream);
 		    patstream = NULL;
 		} else if (ret != match) {
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
 		    if (path == NULL) {
 		        path = xmlGetNodePath(
 		                       xmlTextReaderCurrentNode(reader));
 		    }
+#endif
 		    fprintf(stderr,
 		            "xmlPatternMatch and xmlStreamPush disagree\n");
-		    fprintf(stderr,
-		            "  pattern %s node %s\n",
-			    pattern, path);
+                    if (path != NULL)
+                        fprintf(stderr, "  pattern %s node %s\n",
+                                pattern, path);
+                    else
+		        fprintf(stderr, "  pattern %s node %s\n",
+			    pattern, xmlTextReaderConstName(reader));
 		}
-		
 
-	    } 
+	    }
 	    if ((type == XML_READER_TYPE_END_ELEMENT) ||
 	        ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
 	        ret = xmlStreamPop(patstream);
@@ -1811,7 +1829,7 @@
     xmlParserInputBufferPtr input = NULL;
 
     if (memory) {
-	if (stat(filename, &info) < 0) 
+	if (stat(filename, &info) < 0)
 	    return;
 	if ((fd = open(filename, O_RDONLY)) < 0)
 	    return;
@@ -1980,7 +1998,7 @@
         namespaces[i++] = ns->prefix;
     }
     namespaces[i++] = NULL;
-    namespaces[i++] = NULL;
+    namespaces[i] = NULL;
 
     if (pattern != NULL) {
         patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict,
@@ -2040,10 +2058,104 @@
 }
 #endif /* LIBXML_READER_ENABLED */
 
+#ifdef LIBXML_XPATH_ENABLED
 /************************************************************************
- * 									*
- * 			Tree Test processing				*
- * 									*
+ *									*
+ *			XPath Query                                     *
+ *									*
+ ************************************************************************/
+
+static void doXPathDump(xmlXPathObjectPtr cur) {
+    switch(cur->type) {
+        case XPATH_NODESET: {
+            int i;
+            xmlNodePtr node;
+#ifdef LIBXML_OUTPUT_ENABLED
+            xmlSaveCtxtPtr ctxt;
+
+            if (cur->nodesetval->nodeNr <= 0) {
+                fprintf(stderr, "XPath set is empty\n");
+                progresult = XMLLINT_ERR_XPATH;
+                break;
+            }
+            ctxt = xmlSaveToFd(1, NULL, 0);
+            if (ctxt == NULL) {
+                fprintf(stderr, "Out of memory for XPath\n");
+                progresult = XMLLINT_ERR_MEM;
+                return;
+            }
+            for (i = 0;i < cur->nodesetval->nodeNr;i++) {
+                node = cur->nodesetval->nodeTab[i];
+                xmlSaveTree(ctxt, node);
+            }
+            xmlSaveClose(ctxt);
+#else
+            printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr);
+#endif
+	    break;
+        }
+        case XPATH_BOOLEAN:
+	    if (cur->boolval) printf("true");
+	    else printf("false");
+	    break;
+        case XPATH_NUMBER:
+	    switch (xmlXPathIsInf(cur->floatval)) {
+	    case 1:
+		printf("Infinity");
+		break;
+	    case -1:
+		printf("-Infinity");
+		break;
+	    default:
+		if (xmlXPathIsNaN(cur->floatval)) {
+		    printf("NaN");
+		} else {
+		    printf("%0g", cur->floatval);
+		}
+	    }
+	    break;
+        case XPATH_STRING:
+	    printf("%s", (const char *) cur->stringval);
+	    break;
+        case XPATH_UNDEFINED:
+	    fprintf(stderr, "XPath Object is uninitialized\n");
+            progresult = XMLLINT_ERR_XPATH;
+	    break;
+	default:
+	    fprintf(stderr, "XPath object of unexpected type\n");
+            progresult = XMLLINT_ERR_XPATH;
+	    break;
+    }
+}
+
+static void doXPathQuery(xmlDocPtr doc, const char *query) {
+    xmlXPathContextPtr ctxt;
+    xmlXPathObjectPtr res;
+
+    ctxt = xmlXPathNewContext(doc);
+    if (ctxt == NULL) {
+        fprintf(stderr, "Out of memory for XPath\n");
+        progresult = XMLLINT_ERR_MEM;
+        return;
+    }
+    ctxt->node = xmlDocGetRootElement(doc);
+    res = xmlXPathEval(BAD_CAST query, ctxt);
+    xmlXPathFreeContext(ctxt);
+
+    if (res == NULL) {
+        fprintf(stderr, "XPath evaluation failure\n");
+        progresult = XMLLINT_ERR_XPATH;
+        return;
+    }
+    doXPathDump(res);
+    xmlXPathFreeObject(res);
+}
+#endif /* LIBXML_XPATH_ENABLED */
+
+/************************************************************************
+ *									*
+ *			Tree Test processing				*
+ *									*
  ************************************************************************/
 static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
     xmlDocPtr doc = NULL;
@@ -2053,7 +2165,7 @@
 
     if ((timing) && (!repeat))
 	startTimer();
-    
+
 
 #ifdef LIBXML_TREE_ENABLED
     if (filename == NULL) {
@@ -2104,7 +2216,7 @@
 	int fd;
 	struct stat info;
 	const char *base;
-	if (stat(filename, &info) < 0) 
+	if (stat(filename, &info) < 0)
 	    return;
 	if ((fd = open(filename, O_RDONLY)) < 0)
 	    return;
@@ -2114,7 +2226,7 @@
 
 	doc = htmlReadMemory((char *) base, info.st_size, filename,
 	                     NULL, options);
-	    
+
 	munmap((char *) base, info.st_size);
 	close(fd);
     }
@@ -2165,6 +2277,8 @@
 			doc = NULL;
 		    }
 	        }
+                if (f != stdin)
+                    fclose(f);
 	    }
 	} else
 #endif /* LIBXML_PUSH_ENABLED */
@@ -2199,7 +2313,7 @@
 		ctxt = xmlNewParserCtxt();
 	    else
 	        ctxt = rectxt;
-	    if (ctxt == NULL) {	      
+	    if (ctxt == NULL) {
 	        doc = NULL;
 	    } else {
 	        ctxt->sax->error = xmlHTMLError;
@@ -2217,7 +2331,7 @@
 	    int fd;
 	    struct stat info;
 	    const char *base;
-	    if (stat(filename, &info) < 0) 
+	    if (stat(filename, &info) < 0)
 		return;
 	    if ((fd = open(filename, O_RDONLY)) < 0)
 		return;
@@ -2231,7 +2345,7 @@
 	    else
 		doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
 			                filename, NULL, options);
-	        
+
 	    munmap((char *) base, info.st_size);
 	    close(fd);
 #endif
@@ -2243,7 +2357,7 @@
 		ctxt = xmlNewParserCtxt();
 	    else
 	        ctxt = rectxt;
-	    if (ctxt == NULL) {	      
+	    if (ctxt == NULL) {
 	        doc = NULL;
 	    } else {
 		doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
@@ -2306,6 +2420,12 @@
     }
 #endif
 
+#ifdef LIBXML_XPATH_ENABLED
+    if (xpathquery != NULL) {
+        doXPathQuery(doc, xpathquery);
+    }
+#endif
+
 #ifdef LIBXML_DEBUG_ENABLED
 #ifdef LIBXML_XPATH_ENABLED
     /*
@@ -2364,7 +2484,7 @@
 		    }
 		}
 	    }
-	}    
+	}
     }else
 #endif /* LIBXML_VALID_ENABLED */
 #ifdef LIBXML_READER_ENABLED
@@ -2391,14 +2511,14 @@
 		    htmlSaveFile(output ? output : "-", doc);
 		}
 		else if (encoding != NULL) {
-		    if ( format ) {
+		    if (format == 1) {
 			htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
 		    }
 		    else {
 			htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
 		    }
 		}
-		else if (format) {
+		else if (format == 1) {
 		    htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
 		}
 		else {
@@ -2429,9 +2549,25 @@
 	        xmlChar *result = NULL;
 		int size;
 
-		size = xmlC14NDocDumpMemory(doc, NULL, 0, NULL, 1, &result);
+		size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
 		if (size >= 0) {
-		    write(1, result, size);
+		    if (write(1, result, size) == -1) {
+		        fprintf(stderr, "Can't write data\n");
+		    }
+		    xmlFree(result);
+		} else {
+		    fprintf(stderr, "Failed to canonicalize\n");
+		    progresult = XMLLINT_ERR_OUT;
+		}
+	    } else if (canonical) {
+	        xmlChar *result = NULL;
+		int size;
+
+		size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
+		if (size >= 0) {
+		    if (write(1, result, size) == -1) {
+		        fprintf(stderr, "Can't write data\n");
+		    }
 		    xmlFree(result);
 		} else {
 		    fprintf(stderr, "Failed to canonicalize\n");
@@ -2442,9 +2578,11 @@
 	        xmlChar *result = NULL;
 		int size;
 
-		size = xmlC14NDocDumpMemory(doc, NULL, 1, NULL, 1, &result);
+		size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
 		if (size >= 0) {
-		    write(1, result, size);
+		    if (write(1, result, size) == -1) {
+		        fprintf(stderr, "Can't write data\n");
+		    }
 		    xmlFree(result);
 		} else {
 		    fprintf(stderr, "Failed to canonicalize\n");
@@ -2458,13 +2596,13 @@
 		int len;
 
 		if (encoding != NULL) {
-		    if ( format ) {
+		    if (format == 1) {
 		        xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
-		    } else { 
+		    } else {
 			xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
 		    }
 		} else {
-		    if (format)
+		    if (format == 1)
 			xmlDocDumpFormatMemory(doc, &result, &len, 1);
 		    else
 			xmlDocDumpMemory(doc, &result, &len);
@@ -2473,7 +2611,9 @@
 		    fprintf(stderr, "Failed to save\n");
 		    progresult = XMLLINT_ERR_OUT;
 		} else {
-		    write(1, result, len);
+		    if (write(1, result, len) == -1) {
+		        fprintf(stderr, "Can't write data\n");
+		    }
 		    xmlFree(result);
 		}
 
@@ -2483,7 +2623,7 @@
 		xmlSaveFile(output ? output : "-", doc);
 	    } else if (oldout) {
 	        if (encoding != NULL) {
-		    if ( format ) {
+		    if (format == 1) {
 			ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
 						   encoding, 1);
 		    }
@@ -2496,7 +2636,7 @@
 				output ? output : "-");
 			progresult = XMLLINT_ERR_OUT;
 		    }
-		} else if (format) {
+		} else if (format == 1) {
 		    ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
 		    if (ret < 0) {
 			fprintf(stderr, "failed save to %s\n",
@@ -2525,8 +2665,15 @@
 	        xmlSaveCtxtPtr ctxt;
 		int saveOpts = 0;
 
-                if (format)
+                if (format == 1)
 		    saveOpts |= XML_SAVE_FORMAT;
+                else if (format == 2)
+                    saveOpts |= XML_SAVE_WSNONSIG;
+
+#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
+                if (xmlout)
+                    saveOpts |= XML_SAVE_AS_XML;
+#endif
 
 		if (output == NULL)
 		    ctxt = xmlSaveToFd(1, encoding, saveOpts);
@@ -2580,9 +2727,9 @@
 	    startTimer();
 	}
 	if (dtdvalid != NULL)
-	    dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid); 
+	    dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
 	else
-	    dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL); 
+	    dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
 	if ((timing) && (!repeat)) {
 	    endTimer("Parsing DTD");
 	}
@@ -2772,9 +2919,9 @@
 }
 
 /************************************************************************
- * 									*
- * 			Usage and Main					*
- * 									*
+ *									*
+ *			Usage and Main					*
+ *									*
  ************************************************************************/
 
 static void showVersion(const char *name) {
@@ -2788,29 +2935,30 @@
     if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns ");
     if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer ");
     if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 ");
-    if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP "); 
-    if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP "); 
+    if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
+    if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
     if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid ");
-    if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML "); 
-    if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy "); 
-    if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N "); 
-    if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog "); 
-    if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath "); 
-    if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer "); 
-    if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude "); 
-    if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv "); 
-    if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X "); 
-    if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode "); 
-    if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps "); 
-    if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata "); 
-    if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr "); 
-    if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas "); 
-    if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron "); 
-    if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules "); 
-    if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug "); 
-    if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug "); 
-    if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug "); 
+    if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
+    if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
+    if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N ");
+    if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog ");
+    if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath ");
+    if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer ");
+    if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude ");
+    if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv ");
+    if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X ");
+    if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
+    if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
+    if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata ");
+    if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr ");
+    if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas ");
+    if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
+    if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
+    if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
+    if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
+    if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug ");
     if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib ");
+    if (xmlHasFeature(XML_WITH_LZMA)) fprintf(stderr, "Lzma ");
     fprintf(stderr, "\n");
 }
 
@@ -2837,6 +2985,7 @@
     printf("\t--recover : output what was parsable on broken XML documents\n");
     printf("\t--huge : remove any internal arbitrary parser limits\n");
     printf("\t--noent : substitute entity references by their value\n");
+    printf("\t--noenc : ignore any encoding specified inside the document\n");
     printf("\t--noout : don't output the result tree\n");
     printf("\t--path 'paths': provide a set of paths for resources\n");
     printf("\t--load-trace : print trace of all external entites loaded\n");
@@ -2862,6 +3011,7 @@
 #ifdef LIBXML_HTML_ENABLED
     printf("\t--html : use the HTML parser\n");
     printf("\t--xmlout : force to use the XML serializer when using --html\n");
+    printf("\t--nodefdtd : do not default HTML doctype\n");
 #endif
 #ifdef LIBXML_PUSH_ENABLED
     printf("\t--push : use the push mode of the parser\n");
@@ -2877,8 +3027,13 @@
     printf("\t--format : reformat/reindent the input\n");
     printf("\t--encode encoding : output in the given encoding\n");
     printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
+    printf("\t--pretty STYLE : pretty-print in a particular style\n");
+    printf("\t                 0 Do not pretty print\n");
+    printf("\t                 1 Format the XML content, as --format\n");
+    printf("\t                 2 Add whitespace inside tags, preserving content\n");
 #endif /* LIBXML_OUTPUT_ENABLED */
-    printf("\t--c14n : save in W3C canonical format (with comments)\n");
+    printf("\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
+    printf("\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
     printf("\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
 #ifdef LIBXML_C14N_ENABLED
 #endif /* LIBXML_C14N_ENABLED */
@@ -2918,6 +3073,9 @@
 #endif
     printf("\t--sax: do not build a tree but work just at the SAX level\n");
     printf("\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
+#ifdef LIBXML_XPATH_ENABLED
+    printf("\t--xpath expr: evaluate the XPath expression, inply --noout\n");
+#endif
 
     printf("\nLibxml project home page: http://xmlsoft.org/\n");
     printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
@@ -2944,7 +3102,7 @@
     int files = 0;
     int version = 0;
     const char* indent;
-    
+
     if (argc <= 1) {
 	usage(argv[0]);
 	return(1);
@@ -2964,7 +3122,7 @@
 	         (!strcmp(argv[i], "--shell"))) {
 	    shell++;
             noout = 1;
-        } else 
+        } else
 #endif
 #ifdef LIBXML_TREE_ENABLED
 	if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
@@ -2982,6 +3140,10 @@
 	         (!strcmp(argv[i], "--noent"))) {
 	    noent++;
 	    options |= XML_PARSE_NOENT;
+	} else if ((!strcmp(argv[i], "-noenc")) ||
+	         (!strcmp(argv[i], "--noenc"))) {
+	    noenc++;
+	    options |= XML_PARSE_IGNORE_ENC;
 	} else if ((!strcmp(argv[i], "-nsclean")) ||
 	         (!strcmp(argv[i], "--nsclean"))) {
 	    options |= XML_PARSE_NSCLEAN;
@@ -3020,6 +3182,10 @@
 	else if ((!strcmp(argv[i], "-xmlout")) ||
 	         (!strcmp(argv[i], "--xmlout"))) {
 	    xmlout++;
+	} else if ((!strcmp(argv[i], "-nodefdtd")) ||
+	         (!strcmp(argv[i], "--nodefdtd"))) {
+            nodefdtd++;
+	    options |= HTML_PARSE_NODEFDTD;
         }
 #endif /* LIBXML_HTML_ENABLED */
 	else if ((!strcmp(argv[i], "-loaddtd")) ||
@@ -3133,19 +3299,24 @@
 		 (!strcmp(argv[i], "--debugent"))) {
 	    debugent++;
 	    xmlParserDebugEntities = 1;
-	} 
+	}
 #endif
 #ifdef LIBXML_C14N_ENABLED
 	else if ((!strcmp(argv[i], "-c14n")) ||
 		 (!strcmp(argv[i], "--c14n"))) {
 	    canonical++;
 	    options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
-	} 
+	}
+	else if ((!strcmp(argv[i], "-c14n11")) ||
+		 (!strcmp(argv[i], "--c14n11"))) {
+	    canonical_11++;
+	    options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
+	}
 	else if ((!strcmp(argv[i], "-exc-c14n")) ||
 		 (!strcmp(argv[i], "--exc-c14n"))) {
 	    exc_canonical++;
 	    options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
-	} 
+	}
 #endif
 #ifdef LIBXML_CATALOG_ENABLED
 	else if ((!strcmp(argv[i], "-catalogs")) ||
@@ -3154,7 +3325,7 @@
 	} else if ((!strcmp(argv[i], "-nocatalogs")) ||
 		 (!strcmp(argv[i], "--nocatalogs"))) {
 	    nocatalogs++;
-	} 
+	}
 #endif
 	else if ((!strcmp(argv[i], "-encode")) ||
 	         (!strcmp(argv[i], "--encode"))) {
@@ -3184,10 +3355,21 @@
 	         (!strcmp(argv[i], "--format"))) {
 	     noblanks++;
 #ifdef LIBXML_OUTPUT_ENABLED
-	     format++;
+	     format = 1;
 #endif /* LIBXML_OUTPUT_ENABLED */
 	     xmlKeepBlanksDefault(0);
 	}
+	else if ((!strcmp(argv[i], "-pretty")) ||
+	         (!strcmp(argv[i], "--pretty"))) {
+	     i++;
+#ifdef LIBXML_OUTPUT_ENABLED
+	     format = atoi(argv[i]);
+#endif /* LIBXML_OUTPUT_ENABLED */
+	     if (format == 1) {
+	         noblanks++;
+	         xmlKeepBlanksDefault(0);
+	     }
+	}
 #ifdef LIBXML_READER_ENABLED
 	else if ((!strcmp(argv[i], "-stream")) ||
 	         (!strcmp(argv[i], "--stream"))) {
@@ -3202,16 +3384,17 @@
 #ifdef LIBXML_SAX1_ENABLED
 	else if ((!strcmp(argv[i], "-sax1")) ||
 	         (!strcmp(argv[i], "--sax1"))) {
-	     sax1++;
+	    sax1++;
+	    options |= XML_PARSE_SAX1;
 	}
 #endif /* LIBXML_SAX1_ENABLED */
 	else if ((!strcmp(argv[i], "-sax")) ||
 	         (!strcmp(argv[i], "--sax"))) {
-	     sax++;
+	    sax++;
 	}
 	else if ((!strcmp(argv[i], "-chkregister")) ||
 	         (!strcmp(argv[i], "--chkregister"))) {
-	     chkregister++;
+	    chkregister++;
 #ifdef LIBXML_SCHEMAS_ENABLED
 	} else if ((!strcmp(argv[i], "-relaxng")) ||
 	         (!strcmp(argv[i], "--relaxng"))) {
@@ -3252,6 +3435,13 @@
 	    i++;
 	    pattern = argv[i];
 #endif
+#ifdef LIBXML_XPATH_ENABLED
+        } else if ((!strcmp(argv[i], "-xpath")) ||
+                   (!strcmp(argv[i], "--xpath"))) {
+	    i++;
+	    noout++;
+	    xpathquery = argv[i];
+#endif
 	} else if ((!strcmp(argv[i], "-oldxml10")) ||
 	           (!strcmp(argv[i], "--oldxml10"))) {
 	    oldxml10++;
@@ -3289,12 +3479,12 @@
 	xmlRegisterNodeDefault(registerNode);
 	xmlDeregisterNodeDefault(deregisterNode);
     }
-    
+
     indent = getenv("XMLLINT_INDENT");
     if(indent != NULL) {
 	xmlTreeIndentString = indent;
     }
-    
+
 
     defaultEntityLoader = xmlGetExternalEntityLoader();
     xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
@@ -3316,7 +3506,7 @@
 	xmlGenericError(xmlGenericErrorContext,
 	 "<html><head><title>%s output</title></head>\n",
 		argv[0]);
-	xmlGenericError(xmlGenericErrorContext, 
+	xmlGenericError(xmlGenericErrorContext,
 	 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
 		argv[0]);
     }
@@ -3330,7 +3520,7 @@
 	xmlSchematronParserCtxtPtr ctxt;
 
         /* forces loading the DTDs */
-        xmlLoadExtDtdDefaultValue |= 1; 
+        xmlLoadExtDtdDefaultValue |= 1;
 	options |= XML_PARSE_DTDLOAD;
 	if (timing) {
 	    startTimer();
@@ -3364,7 +3554,7 @@
 	xmlRelaxNGParserCtxtPtr ctxt;
 
         /* forces loading the DTDs */
-        xmlLoadExtDtdDefaultValue |= 1; 
+        xmlLoadExtDtdDefaultValue |= 1;
 	options |= XML_PARSE_DTDLOAD;
 	if (timing) {
 	    startTimer();
@@ -3444,7 +3634,7 @@
 	         (!strcmp(argv[i], "--dtdvalid"))) {
 	    i++;
 	    continue;
-        } 
+        }
 	if ((!strcmp(argv[i], "-path")) ||
                    (!strcmp(argv[i], "--path"))) {
             i++;
@@ -3466,6 +3656,11 @@
 	    i++;
 	    continue;
         }
+	if ((!strcmp(argv[i], "-pretty")) ||
+	         (!strcmp(argv[i], "--pretty"))) {
+	    i++;
+	    continue;
+        }
 	if ((!strcmp(argv[i], "-schema")) ||
 	         (!strcmp(argv[i], "--schema"))) {
 	    i++;
@@ -3483,6 +3678,13 @@
 	    continue;
 	}
 #endif
+#ifdef LIBXML_XPATH_ENABLED
+        if ((!strcmp(argv[i], "-xpath")) ||
+	    (!strcmp(argv[i], "--xpath"))) {
+	    i++;
+	    continue;
+	}
+#endif
 	if ((timing) && (repeat))
 	    startTimer();
 	/* Remember file names.  "-" means stdin.  <sven@zen.org> */
@@ -3534,7 +3736,7 @@
 	    }
 	}
     }
-    if (generate) 
+    if (generate)
 	parseAndPrintFile(NULL, NULL);
     if ((htmlout) && (!nowrap)) {
 	xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
diff --git a/xmlmemory.c b/xmlmemory.c
index 433abb8..a0ab953 100644
--- a/xmlmemory.c
+++ b/xmlmemory.c
@@ -205,7 +205,8 @@
 
     if (xmlMemTraceBlockAt == ret) {
 	xmlGenericError(xmlGenericErrorContext,
-			"%p : Malloc(%ld) Ok\n", xmlMemTraceBlockAt, size);
+			"%p : Malloc(%lu) Ok\n", xmlMemTraceBlockAt,
+			(long unsigned)size);
 	xmlMallocBreakpoint();
     }
 
@@ -273,7 +274,8 @@
 
     if (xmlMemTraceBlockAt == ret) {
 	xmlGenericError(xmlGenericErrorContext,
-			"%p : Malloc(%ld) Ok\n", xmlMemTraceBlockAt, size);
+			"%p : Malloc(%lu) Ok\n", xmlMemTraceBlockAt,
+			(long unsigned)size);
 	xmlMallocBreakpoint();
     }
 
@@ -348,8 +350,9 @@
     }
     if (xmlMemTraceBlockAt == ptr) {
 	xmlGenericError(xmlGenericErrorContext,
-			"%p : Realloced(%ld -> %ld) Ok\n",
-			xmlMemTraceBlockAt, p->mh_size, size);
+			"%p : Realloced(%lu -> %lu) Ok\n",
+			xmlMemTraceBlockAt, (long unsigned)p->mh_size,
+			(long unsigned)size);
 	xmlMallocBreakpoint();
     }
     p->mh_tag = MEMTAG;
diff --git a/xmlreader.c b/xmlreader.c
index d42b1a0..97c71ab 100644
--- a/xmlreader.c
+++ b/xmlreader.c
@@ -1,7 +1,7 @@
 /*
  * xmlreader.c: implements the xmlTextReader streaming node API
  *
- * NOTE: 
+ * NOTE:
  *   XmlTextReader.Normalization Property won't be supported, since
  *     it makes the parser non compliant to the XML recommendation
  *
@@ -73,7 +73,7 @@
  *
  * macro to flag unimplemented blocks
  */
-#define TODO 								\
+#define TODO								\
     xmlGenericError(xmlGenericErrorContext,				\
 	    "Unimplemented block at %s:%d\n",				\
             __FILE__, __LINE__);
@@ -128,8 +128,8 @@
     endElementNsSAX2Func	endElementNs;  /* idem */
     charactersSAXFunc		characters;
     cdataBlockSAXFunc		cdataBlock;
-    unsigned int 		base;	/* base of the segment in the input */
-    unsigned int 		cur;	/* current position in the input */
+    unsigned int		base;	/* base of the segment in the input */
+    unsigned int		cur;	/* current position in the input */
     xmlNodePtr			node;	/* current node */
     xmlNodePtr			curnode;/* current attribute node */
     int				depth;  /* depth of the current node */
@@ -207,7 +207,7 @@
  * current scope
  */
 #define DICT_FREE(str)						\
-	if ((str) && ((!dict) || 				\
+	if ((str) && ((!dict) ||				\
 	    (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))	\
 	    xmlFree((char *)(str));
 
@@ -252,7 +252,7 @@
     if (doc == NULL) return(-1);
     if (attr == NULL) return(-1);
     table = (xmlIDTablePtr) doc->ids;
-    if (table == NULL) 
+    if (table == NULL)
         return(-1);
 
     ID = xmlNodeListGetString(doc, attr->children, 1);
@@ -842,7 +842,7 @@
 		    break;
 		}
 
-	    } else 
+	    } else
 		break;
 	}
 	/*
@@ -891,7 +891,7 @@
 	if (reader->state != XML_TEXTREADER_DONE) {
 	    s = inbuf->use - reader->cur;
 	    val = xmlParseChunk(reader->ctxt,
-		    (const char *) &inbuf->content[reader->cur], 
+		    (const char *) &inbuf->content[reader->cur],
 		    s, 1);
 	    reader->cur = inbuf->use;
 	    reader->state  = XML_TEXTREADER_DONE;
@@ -1031,7 +1031,7 @@
 	int ret;
 
 	if (reader->rngFullNode != NULL) {
-	    if (node == reader->rngFullNode) 
+	    if (node == reader->rngFullNode)
 	        reader->rngFullNode = NULL;
 	    return;
 	}
@@ -1066,7 +1066,7 @@
 	     */
 	    if ((node->children == NULL) && (ctxt->sax != NULL) &&
 		(ctxt->sax->getEntity != NULL)) {
-		node->children = (xmlNodePtr) 
+		node->children = (xmlNodePtr)
 		    ctxt->sax->getEntity(ctxt, node->name);
 	    }
 
@@ -1256,7 +1256,7 @@
     xmlTextReaderState oldstate = XML_TEXTREADER_START;
     xmlNodePtr oldnode = NULL;
 
-   
+
     if (reader == NULL)
 	return(-1);
     reader->curnode = NULL;
@@ -1436,7 +1436,7 @@
 	/*
 	 * Cleanup of the old node
 	 */
-	if ((reader->preserves == 0) &&
+	if ((oldnode != NULL) && (reader->preserves == 0) &&
 #ifdef LIBXML_XINCLUDE_ENABLED
 	    (reader->in_xinclude == 0) &&
 #endif
@@ -1489,7 +1489,7 @@
 	 (xmlStrEqual(reader->node->ns->href, XINCLUDE_OLD_NS)))) {
 	if (reader->xincctxt == NULL) {
 	    reader->xincctxt = xmlXIncludeNewContext(reader->ctxt->myDoc);
-	    xmlXIncludeSetFlags(reader->xincctxt, 
+	    xmlXIncludeSetFlags(reader->xincctxt,
 	                        reader->parserFlags & (~XML_PARSE_NOXINCNODE));
 	}
 	/*
@@ -1502,7 +1502,7 @@
     if ((reader->node != NULL) && (reader->node->type == XML_XINCLUDE_START)) {
         reader->in_xinclude++;
 	goto get_next_node;
-    } 
+    }
     if ((reader->node != NULL) && (reader->node->type == XML_XINCLUDE_END)) {
         reader->in_xinclude--;
 	goto get_next_node;
@@ -1520,7 +1520,7 @@
 	 */
 	if ((reader->node->children == NULL) && (reader->ctxt->sax != NULL) &&
 	    (reader->ctxt->sax->getEntity != NULL)) {
-	    reader->node->children = (xmlNodePtr) 
+	    reader->node->children = (xmlNodePtr)
 		reader->ctxt->sax->getEntity(reader->ctxt, reader->node->name);
 	}
 
@@ -1548,7 +1548,7 @@
     if ((reader->validate) && (reader->node != NULL)) {
 	xmlNodePtr node = reader->node;
 
-	if ((node->type == XML_ELEMENT_NODE) && 
+	if ((node->type == XML_ELEMENT_NODE) &&
             ((reader->state != XML_TEXTREADER_END) &&
 	     (reader->state != XML_TEXTREADER_BACKTRACK))) {
 	    xmlTextReaderValidatePush(reader);
@@ -1573,7 +1573,7 @@
 #endif /* LIBXML_PATTERN_ENABLED */
 #ifdef LIBXML_SCHEMAS_ENABLED
     if ((reader->validate == XML_TEXTREADER_VALIDATE_XSD) &&
-        (reader->xsdValidErrors == 0) && 
+        (reader->xsdValidErrors == 0) &&
 	(reader->xsdValidCtxt != NULL)) {
 	reader->xsdValidErrors = !xmlSchemaIsValid(reader->xsdValidCtxt);
     }
@@ -1664,7 +1664,7 @@
  * Reads the contents of the current node, including child nodes and markup.
  *
  * Returns a string containing the XML content, or NULL if the current node
- *         is neither an element nor attribute, or has no child nodes. The 
+ *         is neither an element nor attribute, or has no child nodes. The
  *         string must be deallocated by the caller.
  */
 xmlChar *
@@ -1709,9 +1709,9 @@
  *
  * Reads the contents of the current node, including child nodes and markup.
  *
- * Returns a string containing the XML content, or NULL if the current node
- *         is neither an element nor attribute, or has no child nodes. The 
- *         string must be deallocated by the caller.
+ * Returns a string containing the node and any XML content, or NULL if the 
+ *         current node cannot be serialized. The string must be deallocated 
+ *         by the caller.
  */
 xmlChar *
 xmlTextReaderReadOuterXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)
@@ -1726,7 +1726,11 @@
     if (xmlTextReaderExpand(reader) == NULL) {
         return NULL;
     }
-    node = xmlDocCopyNode(node, doc, 1);
+	if (node->type == XML_DTD_NODE) {
+		node = (xmlNodePtr) xmlCopyDtd((xmlDtdPtr) node);
+	} else {
+		node = xmlDocCopyNode(node, doc, 1);
+	}
     buff = xmlBufferCreate();
     if (xmlNodeDump(buff, doc, node, 0, 0) == -1) {
         xmlFreeNode(node);
@@ -2106,7 +2110,7 @@
 	ret->base = 0;
 	ret->cur = 0;
     }
-    
+
     if (ret->ctxt == NULL) {
         xmlGenericError(xmlGenericErrorContext,
 		"xmlNewTextReader : malloc failed\n");
@@ -2214,6 +2218,9 @@
 	xmlFree(reader->patternTab);
     }
 #endif
+    if (reader->faketext != NULL) {
+	xmlFreeNode(reader->faketext);
+    }
     if (reader->ctxt != NULL) {
         if (reader->dict == reader->ctxt->dict)
 	    reader->dict = NULL;
@@ -2235,9 +2242,6 @@
 	xmlFree(reader->sax);
     if ((reader->input != NULL)  && (reader->allocs & XML_TEXTREADER_INPUT))
 	xmlFreeParserInputBuffer(reader->input);
-    if (reader->faketext != NULL) {
-	xmlFreeNode(reader->faketext);
-    }
     if (reader->buffer != NULL)
         xmlBufferFree(reader->buffer);
     if (reader->entTab != NULL)
@@ -2308,7 +2312,7 @@
     if (reader->curnode != NULL)
 	return(NULL);
     /* TODO: handle the xmlDecl */
-    if (reader->node->type != XML_ELEMENT_NODE) 
+    if (reader->node->type != XML_ELEMENT_NODE)
 	return(NULL);
 
     ns = reader->node->nsDef;
@@ -2438,7 +2442,7 @@
 		}
 		ns = reader->node->nsDef;
 		while (ns != NULL) {
-			if ((prefix == NULL && ns->prefix == NULL) || 
+			if ((prefix == NULL && ns->prefix == NULL) ||
 				((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localName)))) {
 				return xmlStrdup(ns->href);
 			}
@@ -2550,7 +2554,7 @@
     if (reader->node == NULL)
 	return(-1);
     /* TODO: handle the xmlDecl */
-    if (reader->node->type != XML_ELEMENT_NODE) 
+    if (reader->node->type != XML_ELEMENT_NODE)
 	return(-1);
 
     reader->curnode = NULL;
@@ -2637,7 +2641,7 @@
 	}
 	return(0);
     }
-    
+
     /*
      * Namespace default decl
      */
@@ -2714,7 +2718,7 @@
 		}
 		ns = reader->node->nsDef;
 		while (ns != NULL) {
-			if ((prefix == NULL && ns->prefix == NULL) || 
+			if ((prefix == NULL && ns->prefix == NULL) ||
 				((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localName)))) {
 				reader->curnode = (xmlNodePtr) ns;
 				return(1);
@@ -2860,7 +2864,7 @@
 	xmlNsPtr ns = (xmlNsPtr) reader->curnode;
 
 	if (reader->faketext == NULL) {
-	    reader->faketext = xmlNewDocText(reader->node->doc, 
+	    reader->faketext = xmlNewDocText(reader->node->doc,
 		                             ns->href);
 	} else {
             if ((reader->faketext->content != NULL) &&
@@ -2898,7 +2902,7 @@
 	doc = reader->ctxt->myDoc;
     if (doc == NULL)
 	return(NULL);
-    
+
     if (doc->encoding == NULL)
 	return(NULL);
     else
@@ -2930,7 +2934,7 @@
 	return(-1);
     if (reader->node == NULL)
 	return(0);
-    
+
     if (reader->curnode != NULL)
 	node = reader->curnode;
     else
@@ -2968,7 +2972,7 @@
 int
 xmlTextReaderNodeType(xmlTextReaderPtr reader) {
     xmlNodePtr node;
-    
+
     if (reader == NULL)
 	return(-1);
     if (reader->node == NULL)
@@ -3064,7 +3068,8 @@
  *
  * The local name of the node.
  *
- * Returns the local name or NULL if not available
+ * Returns the local name or NULL if not available,
+ *   if non NULL it need to be freed by the caller.
  */
 xmlChar *
 xmlTextReaderLocalName(xmlTextReaderPtr reader) {
@@ -3125,7 +3130,8 @@
  *
  * The qualified name of the node, equal to Prefix :LocalName.
  *
- * Returns the local name or NULL if not available
+ * Returns the local name or NULL if not available,
+ *   if non NULL it need to be freed by the caller.
  */
 xmlChar *
 xmlTextReaderName(xmlTextReaderPtr reader) {
@@ -3144,7 +3150,7 @@
 	    if ((node->ns == NULL) ||
 		(node->ns->prefix == NULL))
 		return(xmlStrdup(node->name));
-	    
+
 	    ret = xmlStrdup(node->ns->prefix);
 	    ret = xmlStrcat(ret, BAD_CAST ":");
 	    ret = xmlStrcat(ret, node->name);
@@ -3268,7 +3274,8 @@
  *
  * A shorthand reference to the namespace associated with the node.
  *
- * Returns the prefix or NULL if not available
+ * Returns the prefix or NULL if not available,
+ *    if non NULL it need to be freed by the caller.
  */
 xmlChar *
 xmlTextReaderPrefix(xmlTextReaderPtr reader) {
@@ -3331,7 +3338,8 @@
  *
  * The URI defining the namespace associated with the node.
  *
- * Returns the namespace URI or NULL if not available
+ * Returns the namespace URI or NULL if not available,
+ *    if non NULL it need to be freed by the caller.
  */
 xmlChar *
 xmlTextReaderNamespaceUri(xmlTextReaderPtr reader) {
@@ -3386,7 +3394,8 @@
  *
  * The base URI of the node.
  *
- * Returns the base URI or NULL if not available
+ * Returns the base URI or NULL if not available,
+ *    if non NULL it need to be freed by the caller.
  */
 xmlChar *
 xmlTextReaderBaseUri(xmlTextReaderPtr reader) {
@@ -3644,7 +3653,8 @@
  *
  * The xml:lang scope within which the node resides.
  *
- * Returns the xml:lang value or NULL if none exists.
+ * Returns the xml:lang value or NULL if none exists.,
+ *    if non NULL it need to be freed by the caller.
  */
 xmlChar *
 xmlTextReaderXmlLang(xmlTextReaderPtr reader) {
@@ -3869,7 +3879,7 @@
 xmlTextReaderCurrentNode(xmlTextReaderPtr reader) {
     if (reader == NULL)
 	return(NULL);
-    
+
     if (reader->curnode != NULL)
 	return(reader->curnode);
     return(reader->node);
@@ -3891,7 +3901,7 @@
 
     if (reader == NULL)
 	return(NULL);
-    
+
     if (reader->curnode != NULL)
         cur = reader->curnode;
     else
@@ -3904,7 +3914,7 @@
 	cur->extra |= NODE_IS_SPRESERVED;
     }
     reader->preserves++;
-        
+
     parent = cur->parent;;
     while (parent != NULL) {
         if (parent->type == XML_ELEMENT_NODE)
@@ -3920,7 +3930,7 @@
  * @reader:  the xmlTextReaderPtr used
  * @pattern:  an XPath subset pattern
  * @namespaces: the prefix definitions, array of [URI, prefix] or NULL
- * 
+ *
  * This tells the XML Reader to preserve all nodes matched by the
  * pattern. The caller must also use xmlTextReaderCurrentDoc() to
  * keep an handle on the resulting document once parsing has finished
@@ -3935,7 +3945,7 @@
 
     if ((reader == NULL) || (pattern == NULL))
 	return(-1);
-    
+
     comp = xmlPatterncompile(pattern, reader->dict, 0, namespaces);
     if (comp == NULL)
         return(-1);
@@ -3972,7 +3982,7 @@
  * @reader:  the xmlTextReaderPtr used
  *
  * Hacking interface allowing to get the xmlDocPtr correponding to the
- * current document being accessed by the xmlTextReader. 
+ * current document being accessed by the xmlTextReader.
  * NOTE: as a result of this call, the reader will not destroy the
  *       associated XML document and calling xmlFreeDoc() on the result
  *       is needed once the reader parsing has finished.
@@ -3987,72 +3997,80 @@
         return(reader->doc);
     if ((reader->ctxt == NULL) || (reader->ctxt->myDoc == NULL))
 	return(NULL);
-    
+
     reader->preserve = 1;
     return(reader->ctxt->myDoc);
 }
 
 #ifdef LIBXML_SCHEMAS_ENABLED
+static char *xmlTextReaderBuildMessage(const char *msg, va_list ap);
 
-static char *
-xmlTextReaderBuildMessage(const char *msg, va_list ap);
-
-static void XMLCDECL 
+static void XMLCDECL
 xmlTextReaderValidityError(void *ctxt, const char *msg, ...);
 
-static void XMLCDECL 
+static void XMLCDECL
 xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...);
 
-static void XMLCDECL xmlTextReaderValidityErrorRelay(void *ctx, const char *msg, ...)
+static void XMLCDECL
+xmlTextReaderValidityErrorRelay(void *ctx, const char *msg, ...)
 {
-	xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx;
-	char * str;
-	va_list ap;
+    xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx;
 
-	va_start(ap,msg);
-	str = xmlTextReaderBuildMessage(msg,ap);
-	if (!reader->errorFunc) {
-		xmlTextReaderValidityError(ctx, "%s", str);
-	} else {
-		reader->errorFunc(reader->errorFuncArg, str, XML_PARSER_SEVERITY_VALIDITY_ERROR, NULL /* locator */);
-	}
-	if (str != NULL)
-		xmlFree(str);
-	va_end(ap);
+    char *str;
+
+    va_list ap;
+
+    va_start(ap, msg);
+    str = xmlTextReaderBuildMessage(msg, ap);
+    if (!reader->errorFunc) {
+        xmlTextReaderValidityError(ctx, "%s", str);
+    } else {
+        reader->errorFunc(reader->errorFuncArg, str,
+                          XML_PARSER_SEVERITY_VALIDITY_ERROR,
+                          NULL /* locator */ );
+    }
+    if (str != NULL)
+        xmlFree(str);
+    va_end(ap);
 }
 
-static void XMLCDECL xmlTextReaderValidityWarningRelay(void *ctx, const char *msg, ...)
+static void XMLCDECL
+xmlTextReaderValidityWarningRelay(void *ctx, const char *msg, ...)
 {
-	xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx;
-	char * str;
-	va_list ap;
+    xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx;
 
-	va_start(ap,msg);
-	str = xmlTextReaderBuildMessage(msg,ap);
-	if (!reader->errorFunc) {
-		xmlTextReaderValidityWarning(ctx, "%s", str);
-	} else {
-		reader->errorFunc(reader->errorFuncArg, str, XML_PARSER_SEVERITY_VALIDITY_WARNING, NULL /* locator */);
-	}
-	if (str != NULL)
-		xmlFree(str);
-	va_end(ap);
+    char *str;
+
+    va_list ap;
+
+    va_start(ap, msg);
+    str = xmlTextReaderBuildMessage(msg, ap);
+    if (!reader->errorFunc) {
+        xmlTextReaderValidityWarning(ctx, "%s", str);
+    } else {
+        reader->errorFunc(reader->errorFuncArg, str,
+                          XML_PARSER_SEVERITY_VALIDITY_WARNING,
+                          NULL /* locator */ );
+    }
+    if (str != NULL)
+        xmlFree(str);
+    va_end(ap);
 }
 
-static void 
-xmlTextReaderStructuredError(void *ctxt, xmlErrorPtr error);
+static void
+  xmlTextReaderStructuredError(void *ctxt, xmlErrorPtr error);
 
-static void xmlTextReaderValidityStructuredRelay(void * userData, xmlErrorPtr error)
+static void
+xmlTextReaderValidityStructuredRelay(void *userData, xmlErrorPtr error)
 {
-	xmlTextReaderPtr reader = (xmlTextReaderPtr) userData;
+    xmlTextReaderPtr reader = (xmlTextReaderPtr) userData;
 
-	if (reader->sErrorFunc) {
-		reader->sErrorFunc(reader->errorFuncArg, error);
-	} else {
-		xmlTextReaderStructuredError(reader, error);
-	}
+    if (reader->sErrorFunc) {
+        reader->sErrorFunc(reader->errorFuncArg, error);
+    } else {
+        xmlTextReaderStructuredError(reader, error);
+    }
 }
-
 /**
  * xmlTextReaderRelaxNGSetSchema:
  * @reader:  the xmlTextReaderPtr used
@@ -4102,7 +4120,7 @@
 			reader);
     }
 	if (reader->sErrorFunc != NULL) {
-		xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, 
+		xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
 			xmlTextReaderValidityStructuredRelay,
 			reader);
     }
@@ -4138,15 +4156,15 @@
         if (reader->xsdValidCtxt != NULL) {
 	    if (! reader->xsdPreserveCtxt)
 		xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
-	    reader->xsdValidCtxt = NULL;	    
+	    reader->xsdValidCtxt = NULL;
         }
 	reader->xsdPreserveCtxt = 0;
         if (reader->xsdSchemas != NULL) {
 	    xmlSchemaFree(reader->xsdSchemas);
 	    reader->xsdSchemas = NULL;
-	}	
+	}
 	return(0);
-    }    
+    }
     if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
 	return(-1);
     if (reader->xsdPlug != NULL) {
@@ -4155,7 +4173,7 @@
     }
     if (reader->xsdValidCtxt != NULL) {
 	if (! reader->xsdPreserveCtxt)
-	    xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);	
+	    xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
 	reader->xsdValidCtxt = NULL;
     }
     reader->xsdPreserveCtxt = 0;
@@ -4213,7 +4231,7 @@
 
     if (reader == NULL)
         return(-1);
-    
+
     if (rng == NULL) {
         if (reader->rngValidCtxt != NULL) {
 	    xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
@@ -4243,7 +4261,7 @@
 			 reader);
     }
     if (reader->sErrorFunc != NULL) {
-	xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, 
+	xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
 			xmlTextReaderValidityStructuredRelay,
 			reader);
     }
@@ -4264,7 +4282,7 @@
 			 reader);
     }
 	if (reader->sErrorFunc != NULL) {
-		xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, 
+		xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
 			xmlTextReaderValidityStructuredRelay,
 			reader);
     }
@@ -4293,7 +4311,7 @@
 				    const char *xsd,
 				    xmlSchemaValidCtxtPtr ctxt,
 				    int options ATTRIBUTE_UNUSED)
-{    
+{
     if (reader == NULL)
         return(-1);
 
@@ -4304,7 +4322,7 @@
 	((reader->mode != XML_TEXTREADER_MODE_INITIAL) ||
         (reader->ctxt == NULL)))
 	return(-1);
-        
+
     /* Cleanup previous validation stuff. */
     if (reader->xsdPlug != NULL) {
 	xmlSchemaSAXUnplug(reader->xsdPlug);
@@ -4312,20 +4330,20 @@
     }
     if (reader->xsdValidCtxt != NULL) {
 	if (! reader->xsdPreserveCtxt)
-	    xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);	
+	    xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
 	reader->xsdValidCtxt = NULL;
     }
     reader->xsdPreserveCtxt = 0;
     if (reader->xsdSchemas != NULL) {
 	xmlSchemaFree(reader->xsdSchemas);
 	reader->xsdSchemas = NULL;
-    }    
+    }
 
     if ((xsd == NULL) && (ctxt == NULL)) {
 	/* We just want to deactivate the validation, so get out. */
 	return(0);
-    }    
-    
+    }
+
     if (xsd != NULL) {
 	xmlSchemaParserCtxtPtr pctxt;
 	/* Parse the schema and create validation environment. */
@@ -4357,13 +4375,13 @@
 	    return(-1);
 	}
     } else {
-	/* Use the given validation context. */	
+	/* Use the given validation context. */
 	reader->xsdValidCtxt = ctxt;
 	reader->xsdPreserveCtxt = 1;
 	reader->xsdPlug = xmlSchemaSAXPlug(reader->xsdValidCtxt,
 	    &(reader->ctxt->sax),
 	    &(reader->ctxt->userData));
-	if (reader->xsdPlug == NULL) {	    
+	if (reader->xsdPlug == NULL) {
 	    reader->xsdValidCtxt = NULL;
 	    reader->xsdPreserveCtxt = 0;
 	    return(-1);
@@ -4382,7 +4400,7 @@
 			 reader);
     }
 	if (reader->sErrorFunc != NULL) {
-		xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, 
+		xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,
 			xmlTextReaderValidityStructuredRelay,
 			reader);
     }
@@ -4453,7 +4471,7 @@
 	node = reader->curnode;
     else
 	node = reader->node;
-    
+
     if (XML_NAMESPACE_DECL == node->type)
 	return(1);
     else
@@ -4477,10 +4495,10 @@
     if (reader->doc != NULL)
         doc = reader->doc;
     else if (reader->ctxt != NULL)
-	doc = reader->ctxt->myDoc; 
+	doc = reader->ctxt->myDoc;
     if (doc == NULL)
 	return(NULL);
-    
+
     if (doc->version == NULL)
 	return(NULL);
     else
@@ -4533,20 +4551,20 @@
         va_end(aq);
         if (chars < 0) {
 	    xmlGenericError(xmlGenericErrorContext, "vsnprintf failed !\n");
-	    if (str) 
-	    	xmlFree(str);
-	    return NULL;  
+	    if (str)
+		xmlFree(str);
+	    return NULL;
 	}
 	if ((chars < size) || (size == MAX_ERR_MSG_SIZE))
             break;
         if (chars < MAX_ERR_MSG_SIZE)
-        	size = chars + 1;
+	size = chars + 1;
 	else
 		size = MAX_ERR_MSG_SIZE;
         if ((larger = (char *) xmlRealloc(str, size)) == NULL) {
 	    xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n");
 	    if (str)
-            	xmlFree(str);
+                xmlFree(str);
             return NULL;
         }
         str = larger;
@@ -4582,7 +4600,7 @@
 	    input = ctx->inputTab[ctx->inputNr - 2];
 	if (input != NULL) {
 	    ret = input->line;
-	} 
+	}
 	else {
 	    ret = -1;
 	}
@@ -4597,7 +4615,8 @@
  *
  * Obtain the base URI for the given locator.
  *
- * Returns the base URI or NULL in case of error.
+ * Returns the base URI or NULL in case of error,
+ *    if non NULL it need to be freed by the caller.
  */
 xmlChar *
 xmlTextReaderLocatorBaseURI(xmlTextReaderLocatorPtr locator) {
@@ -4618,7 +4637,7 @@
 	    input = ctx->inputTab[ctx->inputNr - 2];
 	if (input != NULL) {
 	    ret = xmlStrdup(BAD_CAST input->filename);
-	} 
+	}
 	else {
 	    ret = NULL;
 	}
@@ -4628,87 +4647,95 @@
 }
 
 static void
-xmlTextReaderGenericError(void *ctxt, xmlParserSeverities severity, char *str) {
-    xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)ctxt;
-    xmlTextReaderPtr reader = (xmlTextReaderPtr)ctx->_private;
+xmlTextReaderGenericError(void *ctxt, xmlParserSeverities severity,
+                          char *str)
+{
+    xmlParserCtxtPtr ctx = (xmlParserCtxtPtr) ctxt;
+
+    xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx->_private;
 
     if (str != NULL) {
-      if (reader->errorFunc)
-	reader->errorFunc(reader->errorFuncArg,
-			  str,
-			  severity,
-			  (xmlTextReaderLocatorPtr)ctx);
-	xmlFree(str);
+        if (reader->errorFunc)
+            reader->errorFunc(reader->errorFuncArg, str, severity,
+                              (xmlTextReaderLocatorPtr) ctx);
+        xmlFree(str);
     }
 }
 
-static void 
-xmlTextReaderStructuredError(void *ctxt, xmlErrorPtr error) {
-  xmlParserCtxtPtr ctx = (xmlParserCtxtPtr) ctxt;
-  xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx->_private;
+static void
+xmlTextReaderStructuredError(void *ctxt, xmlErrorPtr error)
+{
+    xmlParserCtxtPtr ctx = (xmlParserCtxtPtr) ctxt;
 
-  if (error && reader->sErrorFunc) {
-	reader->sErrorFunc(reader->errorFuncArg,
-			   (xmlErrorPtr) error);
-  }
+    xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx->_private;
+
+    if (error && reader->sErrorFunc) {
+        reader->sErrorFunc(reader->errorFuncArg, (xmlErrorPtr) error);
+    }
 }
 
-static void XMLCDECL 
-xmlTextReaderError(void *ctxt, const char *msg, ...) {
+static void XMLCDECL
+xmlTextReaderError(void *ctxt, const char *msg, ...)
+{
     va_list ap;
 
-    va_start(ap,msg);
+    va_start(ap, msg);
     xmlTextReaderGenericError(ctxt,
                               XML_PARSER_SEVERITY_ERROR,
-	                      xmlTextReaderBuildMessage(msg,ap));
+                              xmlTextReaderBuildMessage(msg, ap));
     va_end(ap);
 
 }
 
-static void XMLCDECL 
-xmlTextReaderWarning(void *ctxt, const char *msg, ...) {
+static void XMLCDECL
+xmlTextReaderWarning(void *ctxt, const char *msg, ...)
+{
     va_list ap;
 
-    va_start(ap,msg);
+    va_start(ap, msg);
     xmlTextReaderGenericError(ctxt,
                               XML_PARSER_SEVERITY_WARNING,
-	                      xmlTextReaderBuildMessage(msg,ap));
+                              xmlTextReaderBuildMessage(msg, ap));
     va_end(ap);
 }
 
-static void XMLCDECL 
-xmlTextReaderValidityError(void *ctxt, const char *msg, ...) {
+static void XMLCDECL
+xmlTextReaderValidityError(void *ctxt, const char *msg, ...)
+{
     va_list ap;
+
     int len = xmlStrlen((const xmlChar *) msg);
 
     if ((len > 1) && (msg[len - 2] != ':')) {
-	/* 
-	 * some callbacks only report locator information: 
-	 * skip them (mimicking behaviour in error.c) 
-	 */
-	va_start(ap,msg);
-	xmlTextReaderGenericError(ctxt,
-				  XML_PARSER_SEVERITY_VALIDITY_ERROR,
-				  xmlTextReaderBuildMessage(msg,ap));
-	va_end(ap);
+        /*
+         * some callbacks only report locator information:
+         * skip them (mimicking behaviour in error.c)
+         */
+        va_start(ap, msg);
+        xmlTextReaderGenericError(ctxt,
+                                  XML_PARSER_SEVERITY_VALIDITY_ERROR,
+                                  xmlTextReaderBuildMessage(msg, ap));
+        va_end(ap);
     }
 }
 
-static void XMLCDECL 
-xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...) {
+static void XMLCDECL
+xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...)
+{
     va_list ap;
+
     int len = xmlStrlen((const xmlChar *) msg);
 
     if ((len != 0) && (msg[len - 1] != ':')) {
-	/* 
-	 * some callbacks only report locator information: 
-	 * skip them (mimicking behaviour in error.c) 
-	 */
-	va_start(ap,msg);
-	xmlTextReaderGenericError(ctxt,
-				  XML_PARSER_SEVERITY_VALIDITY_WARNING,
-				  xmlTextReaderBuildMessage(msg,ap));
-	va_end(ap);
+        /*
+         * some callbacks only report locator information:
+         * skip them (mimicking behaviour in error.c)
+         */
+        va_start(ap, msg);
+        xmlTextReaderGenericError(ctxt,
+                                  XML_PARSER_SEVERITY_VALIDITY_WARNING,
+                                  xmlTextReaderBuildMessage(msg, ap));
+        va_end(ap);
     }
 }
 
@@ -4723,53 +4750,58 @@
  * If @f is NULL, the default error and warning handlers are restored.
  */
 void
-xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader, 
-			     xmlTextReaderErrorFunc f, 
-			     void *arg) {
+xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader,
+                             xmlTextReaderErrorFunc f, void *arg)
+{
     if (f != NULL) {
-	reader->ctxt->sax->error = xmlTextReaderError;
-	reader->ctxt->sax->serror = NULL;
-	reader->ctxt->vctxt.error = xmlTextReaderValidityError;
-	reader->ctxt->sax->warning = xmlTextReaderWarning;
-	reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning;
-	reader->errorFunc = f;
-	reader->sErrorFunc = NULL;
-	reader->errorFuncArg = arg;
+        reader->ctxt->sax->error = xmlTextReaderError;
+        reader->ctxt->sax->serror = NULL;
+        reader->ctxt->vctxt.error = xmlTextReaderValidityError;
+        reader->ctxt->sax->warning = xmlTextReaderWarning;
+        reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning;
+        reader->errorFunc = f;
+        reader->sErrorFunc = NULL;
+        reader->errorFuncArg = arg;
 #ifdef LIBXML_SCHEMAS_ENABLED
-		if (reader->rngValidCtxt) {
-			xmlRelaxNGSetValidErrors(reader->rngValidCtxt,
-				 xmlTextReaderValidityErrorRelay,
-				 xmlTextReaderValidityWarningRelay,
-				 reader);
-			xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL, reader);
-		}
-		if (reader->xsdValidCtxt) {
-			xmlSchemaSetValidErrors(reader->xsdValidCtxt,
-				 xmlTextReaderValidityErrorRelay,
-				 xmlTextReaderValidityWarningRelay,
-				 reader);
-			xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL, reader);
-		}
+        if (reader->rngValidCtxt) {
+            xmlRelaxNGSetValidErrors(reader->rngValidCtxt,
+                                     xmlTextReaderValidityErrorRelay,
+                                     xmlTextReaderValidityWarningRelay,
+                                     reader);
+            xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL,
+                                               reader);
+        }
+        if (reader->xsdValidCtxt) {
+            xmlSchemaSetValidErrors(reader->xsdValidCtxt,
+                                    xmlTextReaderValidityErrorRelay,
+                                    xmlTextReaderValidityWarningRelay,
+                                    reader);
+            xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL,
+                                              reader);
+        }
 #endif
-    }
-    else {
-	/* restore defaults */
-	reader->ctxt->sax->error = xmlParserError;
-	reader->ctxt->vctxt.error = xmlParserValidityError;
-	reader->ctxt->sax->warning = xmlParserWarning;
-	reader->ctxt->vctxt.warning = xmlParserValidityWarning;
-	reader->errorFunc = NULL;
-	reader->sErrorFunc = NULL;
-	reader->errorFuncArg = NULL;
+    } else {
+        /* restore defaults */
+        reader->ctxt->sax->error = xmlParserError;
+        reader->ctxt->vctxt.error = xmlParserValidityError;
+        reader->ctxt->sax->warning = xmlParserWarning;
+        reader->ctxt->vctxt.warning = xmlParserValidityWarning;
+        reader->errorFunc = NULL;
+        reader->sErrorFunc = NULL;
+        reader->errorFuncArg = NULL;
 #ifdef LIBXML_SCHEMAS_ENABLED
-		if (reader->rngValidCtxt) {
-			xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL, reader);
-			xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL, reader);
-		}
-		if (reader->xsdValidCtxt) {
-			xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL, reader);
-			xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL, reader);
-		}
+        if (reader->rngValidCtxt) {
+            xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL,
+                                     reader);
+            xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL,
+                                               reader);
+        }
+        if (reader->xsdValidCtxt) {
+            xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL,
+                                    reader);
+            xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL,
+                                              reader);
+        }
 #endif
     }
 }
@@ -4785,54 +4817,59 @@
  * If @f is NULL, the default error and warning handlers are restored.
  */
 void
-xmlTextReaderSetStructuredErrorHandler(xmlTextReaderPtr reader, 
-					 xmlStructuredErrorFunc f, 
-					 void *arg) {
-  if (f != NULL) {
-	reader->ctxt->sax->error = NULL;
-	reader->ctxt->sax->serror = xmlTextReaderStructuredError;
-	reader->ctxt->vctxt.error = xmlTextReaderValidityError;
-	reader->ctxt->sax->warning = xmlTextReaderWarning;
-	reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning;
-	reader->sErrorFunc = f;
-	reader->errorFunc = NULL;
-	reader->errorFuncArg = arg;
+xmlTextReaderSetStructuredErrorHandler(xmlTextReaderPtr reader,
+                                       xmlStructuredErrorFunc f, void *arg)
+{
+    if (f != NULL) {
+        reader->ctxt->sax->error = NULL;
+        reader->ctxt->sax->serror = xmlTextReaderStructuredError;
+        reader->ctxt->vctxt.error = xmlTextReaderValidityError;
+        reader->ctxt->sax->warning = xmlTextReaderWarning;
+        reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning;
+        reader->sErrorFunc = f;
+        reader->errorFunc = NULL;
+        reader->errorFuncArg = arg;
 #ifdef LIBXML_SCHEMAS_ENABLED
-		if (reader->rngValidCtxt) {
-			xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL, reader);
-			xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
-				xmlTextReaderValidityStructuredRelay,
-				reader);
-		}
-		if (reader->xsdValidCtxt) {
-			xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL, reader);
-			xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, 
-				xmlTextReaderValidityStructuredRelay,
-				reader);
-		}
+        if (reader->rngValidCtxt) {
+            xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL,
+                                     reader);
+            xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
+                                        xmlTextReaderValidityStructuredRelay,
+                                               reader);
+        }
+        if (reader->xsdValidCtxt) {
+            xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL,
+                                    reader);
+            xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,
+                                       xmlTextReaderValidityStructuredRelay,
+                                              reader);
+        }
 #endif
-  }
-  else {
-	/* restore defaults */
-	reader->ctxt->sax->error = xmlParserError;
-	reader->ctxt->sax->serror = NULL;
-	reader->ctxt->vctxt.error = xmlParserValidityError;
-	reader->ctxt->sax->warning = xmlParserWarning;
-	reader->ctxt->vctxt.warning = xmlParserValidityWarning;
-	reader->errorFunc = NULL;
-	reader->sErrorFunc = NULL;
-	reader->errorFuncArg = NULL;
+    } else {
+        /* restore defaults */
+        reader->ctxt->sax->error = xmlParserError;
+        reader->ctxt->sax->serror = NULL;
+        reader->ctxt->vctxt.error = xmlParserValidityError;
+        reader->ctxt->sax->warning = xmlParserWarning;
+        reader->ctxt->vctxt.warning = xmlParserValidityWarning;
+        reader->errorFunc = NULL;
+        reader->sErrorFunc = NULL;
+        reader->errorFuncArg = NULL;
 #ifdef LIBXML_SCHEMAS_ENABLED
-		if (reader->rngValidCtxt) {
-			xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL, reader);
-			xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL, reader);
-		}
-		if (reader->xsdValidCtxt) {
-			xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL, reader);
-			xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL, reader);
-		}
+        if (reader->rngValidCtxt) {
+            xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL,
+                                     reader);
+            xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL,
+                                               reader);
+        }
+        if (reader->xsdValidCtxt) {
+            xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL,
+                                    reader);
+            xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL,
+                                              reader);
+        }
 #endif
-  }
+    }
 }
 
 /**
@@ -4844,17 +4881,19 @@
  * Returns the flag value 1 if valid, 0 if no, and -1 in case of error
  */
 int
-xmlTextReaderIsValid(xmlTextReaderPtr reader) {
-    if (reader == NULL) return(-1);
+xmlTextReaderIsValid(xmlTextReaderPtr reader)
+{
+    if (reader == NULL)
+        return (-1);
 #ifdef LIBXML_SCHEMAS_ENABLED
     if (reader->validate == XML_TEXTREADER_VALIDATE_RNG)
-        return(reader->rngValidErrors == 0);
+        return (reader->rngValidErrors == 0);
     if (reader->validate == XML_TEXTREADER_VALIDATE_XSD)
-        return(reader->xsdValidErrors == 0);
+        return (reader->xsdValidErrors == 0);
 #endif
     if ((reader->ctxt != NULL) && (reader->ctxt->validate == 1))
-	return(reader->ctxt->valid);
-    return(0);
+        return (reader->ctxt->valid);
+    return (0);
 }
 
 /**
@@ -4866,14 +4905,14 @@
  * Retrieve the error callback function and user argument.
  */
 void
-xmlTextReaderGetErrorHandler(xmlTextReaderPtr reader, 
-			     xmlTextReaderErrorFunc *f, 
-			     void **arg) {
-    if (f != NULL) *f = reader->errorFunc;
-    if (arg != NULL) *arg = reader->errorFuncArg;
+xmlTextReaderGetErrorHandler(xmlTextReaderPtr reader,
+                             xmlTextReaderErrorFunc * f, void **arg)
+{
+    if (f != NULL)
+        *f = reader->errorFunc;
+    if (arg != NULL)
+        *arg = reader->errorFuncArg;
 }
-
-
 /************************************************************************
  *									*
  *	New set (2.6.0) of simpler and more flexible APIs		*
@@ -4890,7 +4929,7 @@
  * @options:  a combination of xmlParserOption
  *
  * Setup an XML reader with new options
- * 
+ *
  * Returns 0 in case of success and -1 in case of error.
  */
 int
@@ -5003,8 +5042,8 @@
 	    inputStream->buf = buf;
 	    inputStream->base = inputStream->buf->buffer->content;
 	    inputStream->cur = inputStream->buf->buffer->content;
-	    inputStream->end = 
-		&inputStream->buf->buffer->content[inputStream->buf->buffer->use];
+	    inputStream->end =
+            &inputStream->buf->buffer->content[inputStream->buf->buffer->use];
 
 	    inputPush(reader->ctxt, inputStream);
 	    reader->cur = 0;
@@ -5105,14 +5144,14 @@
         return(-1);
     return(xmlByteConsumed(reader->ctxt));
 }
- 
+
 
 /**
  * xmlReaderWalker:
  * @doc:  a preparsed document
  *
  * Create an xmltextReader for a preparsed document.
- * 
+ *
  * Returns the new reader or NULL in case of error.
  */
 xmlTextReaderPtr
@@ -5153,7 +5192,7 @@
  *
  * Create an xmltextReader for an XML in-memory document.
  * The parsing flags @options are a combination of xmlParserOption.
- * 
+ *
  * Returns the new reader or NULL in case of error.
  */
 xmlTextReaderPtr
@@ -5178,7 +5217,7 @@
  *
  * parse an XML file from the filesystem or the network.
  * The parsing flags @options are a combination of xmlParserOption.
- * 
+ *
  * Returns the new reader or NULL in case of error.
  */
 xmlTextReaderPtr
@@ -5203,7 +5242,7 @@
  *
  * Create an xmltextReader for an XML in-memory document.
  * The parsing flags @options are a combination of xmlParserOption.
- * 
+ *
  * Returns the new reader or NULL in case of error.
  */
 xmlTextReaderPtr
@@ -5239,7 +5278,7 @@
  * The parsing flags @options are a combination of xmlParserOption.
  * NOTE that the file descriptor will not be closed when the
  *      reader is closed or reset.
- * 
+ *
  * Returns the new reader or NULL in case of error.
  */
 xmlTextReaderPtr
@@ -5276,7 +5315,7 @@
  *
  * Create an xmltextReader for an XML document from I/O functions and source.
  * The parsing flags @options are a combination of xmlParserOption.
- * 
+ *
  * Returns the new reader or NULL in case of error.
  */
 xmlTextReaderPtr
@@ -5311,7 +5350,7 @@
  *
  * Setup an xmltextReader to parse a preparsed XML document.
  * This reuses the existing @reader xmlTextReader.
- * 
+ *
  * Returns 0 in case of success and -1 in case of error
  */
 int
@@ -5359,7 +5398,7 @@
  * Setup an xmltextReader to parse an XML in-memory document.
  * The parsing flags @options are a combination of xmlParserOption.
  * This reuses the existing @reader xmlTextReader.
- * 
+ *
  * Returns 0 in case of success and -1 in case of error
  */
 int
@@ -5389,7 +5428,7 @@
  * parse an XML file from the filesystem or the network.
  * The parsing flags @options are a combination of xmlParserOption.
  * This reuses the existing @reader xmlTextReader.
- * 
+ *
  * Returns 0 in case of success and -1 in case of error
  */
 int
@@ -5423,7 +5462,7 @@
  * Setup an xmltextReader to parse an XML in-memory document.
  * The parsing flags @options are a combination of xmlParserOption.
  * This reuses the existing @reader xmlTextReader.
- * 
+ *
  * Returns 0 in case of success and -1 in case of error
  */
 int
@@ -5458,7 +5497,7 @@
  *      reader is closed or reset.
  * The parsing flags @options are a combination of xmlParserOption.
  * This reuses the existing @reader xmlTextReader.
- * 
+ *
  * Returns 0 in case of success and -1 in case of error
  */
 int
@@ -5493,7 +5532,7 @@
  * and source.
  * The parsing flags @options are a combination of xmlParserOption.
  * This reuses the existing @reader xmlTextReader.
- * 
+ *
  * Returns 0 in case of success and -1 in case of error
  */
 int
@@ -5520,6 +5559,7 @@
  *									*
  ************************************************************************/
 #ifdef NOT_USED_YET
+
 /**
  * xmlBase64Decode:
  * @in:  the input buffer
@@ -5535,22 +5575,34 @@
  */
 static int
 xmlBase64Decode(const unsigned char *in, unsigned long *inlen,
-	        unsigned char *to, unsigned long *tolen) {
-    unsigned long incur;		/* current index in in[] */
-    unsigned long inblk;		/* last block index in in[] */
-    unsigned long outcur;		/* current index in out[] */
-    unsigned long inmax;		/* size of in[] */
-    unsigned long outmax;		/* size of out[] */
-    unsigned char cur;			/* the current value read from in[] */
-    unsigned char intmp[4], outtmp[4];	/* temporary buffers for the convert */
-    int nbintmp;			/* number of byte in intmp[] */
-    int is_ignore;			/* cur should be ignored */
-    int is_end = 0;			/* the end of the base64 was found */
+                unsigned char *to, unsigned long *tolen)
+{
+    unsigned long incur;        /* current index in in[] */
+
+    unsigned long inblk;        /* last block index in in[] */
+
+    unsigned long outcur;       /* current index in out[] */
+
+    unsigned long inmax;        /* size of in[] */
+
+    unsigned long outmax;       /* size of out[] */
+
+    unsigned char cur;          /* the current value read from in[] */
+
+    unsigned char intmp[4], outtmp[4];  /* temporary buffers for the convert */
+
+    int nbintmp;                /* number of byte in intmp[] */
+
+    int is_ignore;              /* cur should be ignored */
+
+    int is_end = 0;             /* the end of the base64 was found */
+
     int retval = 1;
+
     int i;
 
     if ((in == NULL) || (inlen == NULL) || (to == NULL) || (tolen == NULL))
-	return(-1);
+        return (-1);
 
     incur = 0;
     inblk = 0;
@@ -5576,16 +5628,17 @@
             cur = 63;
         else if (cur == '.')
             cur = 0;
-        else if (cur == '=') /*no op , end of the base64 stream */
+        else if (cur == '=')    /*no op , end of the base64 stream */
             is_end = 1;
         else {
             is_ignore = 1;
-	    if (nbintmp == 0)
-		inblk = incur;
-	}
+            if (nbintmp == 0)
+                inblk = incur;
+        }
 
         if (!is_ignore) {
             int nbouttmp = 3;
+
             int is_break = 0;
 
             if (is_end) {
@@ -5599,30 +5652,30 @@
                 is_break = 1;
             }
             intmp[nbintmp++] = cur;
-	    /*
-	     * if intmp is full, push the 4byte sequence as a 3 byte
-	     * sequence out
-	     */
+            /*
+             * if intmp is full, push the 4byte sequence as a 3 byte
+             * sequence out
+             */
             if (nbintmp == 4) {
                 nbintmp = 0;
                 outtmp[0] = (intmp[0] << 2) | ((intmp[1] & 0x30) >> 4);
                 outtmp[1] =
                     ((intmp[1] & 0x0F) << 4) | ((intmp[2] & 0x3C) >> 2);
                 outtmp[2] = ((intmp[2] & 0x03) << 6) | (intmp[3] & 0x3F);
-		if (outcur + 3 >= outmax) {
-		    retval = 2;
-		    break;
-		}
+                if (outcur + 3 >= outmax) {
+                    retval = 2;
+                    break;
+                }
 
                 for (i = 0; i < nbouttmp; i++)
-		    to[outcur++] = outtmp[i];
-		inblk = incur;
+                    to[outcur++] = outtmp[i];
+                inblk = incur;
             }
 
             if (is_break) {
-		retval = 0;
+                retval = 0;
                 break;
-	    }
+            }
         }
     }
 
@@ -5635,14 +5688,23 @@
  * Test routine for the xmlBase64Decode function
  */
 #if 0
-int main(int argc, char **argv) {
+int
+main(int argc, char **argv)
+{
     char *input = "  VW4 gcGV0        \n      aXQgdGVzdCAuCg== ";
+
     char output[100];
+
     char output2[100];
+
     char output3[100];
+
     unsigned long inlen = strlen(input);
+
     unsigned long outlen = 100;
+
     int ret;
+
     unsigned long cons, tmp, tmp2, prod;
 
     /*
@@ -5651,25 +5713,28 @@
     ret = xmlBase64Decode(input, &inlen, output, &outlen);
 
     output[outlen] = 0;
-    printf("ret: %d, inlen: %ld , outlen: %ld, output: '%s'\n", ret, inlen, outlen, output);
-    
+    printf("ret: %d, inlen: %ld , outlen: %ld, output: '%s'\n", ret, inlen,
+           outlen, output)indent: Standard input:179: Error:Unmatched #endif
+;
+
     /*
      * output chunking
      */
     cons = 0;
     prod = 0;
     while (cons < inlen) {
-	tmp = 5;
-	tmp2 = inlen - cons;
+        tmp = 5;
+        tmp2 = inlen - cons;
 
-	printf("%ld %ld\n", cons, prod);
-	ret = xmlBase64Decode(&input[cons], &tmp2, &output2[prod], &tmp);
-	cons += tmp2;
-	prod += tmp;
-	printf("%ld %ld\n", cons, prod);
+        printf("%ld %ld\n", cons, prod);
+        ret = xmlBase64Decode(&input[cons], &tmp2, &output2[prod], &tmp);
+        cons += tmp2;
+        prod += tmp;
+        printf("%ld %ld\n", cons, prod);
     }
     output2[outlen] = 0;
-    printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret, cons, prod, output2);
+    printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret, cons,
+           prod, output2);
 
     /*
      * input chunking
@@ -5677,20 +5742,21 @@
     cons = 0;
     prod = 0;
     while (cons < inlen) {
-	tmp = 100 - prod;
-	tmp2 = inlen - cons;
-	if (tmp2 > 5)
-	    tmp2 = 5;
+        tmp = 100 - prod;
+        tmp2 = inlen - cons;
+        if (tmp2 > 5)
+            tmp2 = 5;
 
-	printf("%ld %ld\n", cons, prod);
-	ret = xmlBase64Decode(&input[cons], &tmp2, &output3[prod], &tmp);
-	cons += tmp2;
-	prod += tmp;
-	printf("%ld %ld\n", cons, prod);
+        printf("%ld %ld\n", cons, prod);
+        ret = xmlBase64Decode(&input[cons], &tmp2, &output3[prod], &tmp);
+        cons += tmp2;
+        prod += tmp;
+        printf("%ld %ld\n", cons, prod);
     }
     output3[outlen] = 0;
-    printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret, cons, prod, output3);
-    return(0);
+    printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret, cons,
+           prod, output3);
+    return (0);
 
 }
 #endif
diff --git a/xmlregexp.c b/xmlregexp.c
index 4258a08..aaff33e 100644
--- a/xmlregexp.c
+++ b/xmlregexp.c
@@ -233,6 +233,8 @@
 typedef struct _xmlAutomata xmlRegParserCtxt;
 typedef xmlRegParserCtxt *xmlRegParserCtxtPtr;
 
+#define AM_AUTOMATA_RNG 1
+
 struct _xmlAutomata {
     xmlChar *string;
     xmlChar *cur;
@@ -260,6 +262,7 @@
 
     int determinist;
     int negs;
+    int flags;
 };
 
 struct _xmlRegexp {
@@ -271,6 +274,7 @@
     int nbCounters;
     xmlRegCounter *counters;
     int determinist;
+    int flags;
     /*
      * That's the compact form for determinists automatas
      */
@@ -353,6 +357,8 @@
 static int xmlRegCheckCharacterRange(xmlRegAtomType type, int codepoint,
                   int neg, int start, int end, const xmlChar *blockName);
 
+void xmlAutomataSetFlags(xmlAutomataPtr am, int flags);
+
 /************************************************************************
  *									*
  * 		Regexp memory error handler				*
@@ -434,6 +440,7 @@
     ret->nbCounters = ctxt->nbCounters;
     ret->counters = ctxt->counters;
     ret->determinist = ctxt->determinist;
+    ret->flags = ctxt->flags;
     if (ret->determinist == -1) {
         xmlRegexpIsDeterminist(ret);
     }
@@ -1569,8 +1576,13 @@
 		 *      1. set transition from atom start to new state
 		 *      2. set transition from atom end to this state. 
 		 */
-		xmlFAGenerateEpsilonTransition(ctxt, atom->start, 0);
-		xmlFAGenerateEpsilonTransition(ctxt, atom->stop, ctxt->state);
+                if (to == NULL) {
+                    xmlFAGenerateEpsilonTransition(ctxt, atom->start, 0);
+                    xmlFAGenerateEpsilonTransition(ctxt, atom->stop,
+                                                   ctxt->state);
+                } else {
+                    xmlFAGenerateEpsilonTransition(ctxt, atom->start, to);
+                }
 		break;
 	    case XML_REGEXP_QUANT_MULT:
 		atom->quant = XML_REGEXP_QUANT_ONCE;
@@ -2083,12 +2095,13 @@
                (range2->type == XML_REGEXP_EPSILON)) {
 	return(0);
     } else if (range1->type == range2->type) {
-        if ((range1->type != XML_REGEXP_CHARVAL) ||
-	    (range1->end < range2->start) ||
-	    (range2->end < range1->start))
-	    ret = 1;
-	else
+        if (range1->type != XML_REGEXP_CHARVAL)
+            ret = 1;
+        else if ((range1->end < range2->start) ||
+	         (range2->end < range1->start))
 	    ret = 0;
+	else
+	    ret = 1;
     } else if (range1->type == XML_REGEXP_CHARVAL) {
         int codepoint;
 	int neg = 0;
@@ -2215,7 +2228,7 @@
     if (((range1->neg == 0) && (range2->neg != 0)) ||
         ((range1->neg != 0) && (range2->neg == 0)))
 	ret = !ret;
-    return(1);
+    return(ret);
 }
 
 /**
@@ -2423,6 +2436,7 @@
  * xmlFAEqualAtoms:
  * @atom1:  an atom
  * @atom2:  an atom
+ * @deep: if not set only compare string pointers
  *
  * Compares two atoms to check whether they are the same exactly
  * this is used to remove equivalent transitions
@@ -2430,7 +2444,7 @@
  * Returns 1 if same and 0 otherwise
  */
 static int
-xmlFAEqualAtoms(xmlRegAtomPtr atom1, xmlRegAtomPtr atom2) {
+xmlFAEqualAtoms(xmlRegAtomPtr atom1, xmlRegAtomPtr atom2, int deep) {
     int ret = 0;
 
     if (atom1 == atom2)
@@ -2445,8 +2459,11 @@
 	    ret = 0;
 	    break;
         case XML_REGEXP_STRING:
-	    ret = xmlStrEqual((xmlChar *)atom1->valuep,
-	                      (xmlChar *)atom2->valuep);
+            if (!deep)
+                ret = (atom1->valuep == atom2->valuep);
+            else
+                ret = xmlStrEqual((xmlChar *)atom1->valuep,
+                                  (xmlChar *)atom2->valuep);
 	    break;
         case XML_REGEXP_CHARVAL:
 	    ret = (atom1->codepoint == atom2->codepoint);
@@ -2464,6 +2481,7 @@
  * xmlFACompareAtoms:
  * @atom1:  an atom
  * @atom2:  an atom
+ * @deep: if not set only compare string pointers
  *
  * Compares two atoms to check whether they intersect in some ways,
  * this is used by xmlFAComputesDeterminism and xmlFARecurseDeterminism only
@@ -2471,7 +2489,7 @@
  * Returns 1 if yes and 0 otherwise
  */
 static int
-xmlFACompareAtoms(xmlRegAtomPtr atom1, xmlRegAtomPtr atom2) {
+xmlFACompareAtoms(xmlRegAtomPtr atom1, xmlRegAtomPtr atom2, int deep) {
     int ret = 1;
 
     if (atom1 == atom2)
@@ -2497,8 +2515,11 @@
     }
     switch (atom1->type) {
         case XML_REGEXP_STRING:
-	    ret = xmlRegStrEqualWildcard((xmlChar *)atom1->valuep,
-	                                 (xmlChar *)atom2->valuep);
+            if (!deep)
+                ret = (atom1->valuep != atom2->valuep);
+            else
+                ret = xmlRegStrEqualWildcard((xmlChar *)atom1->valuep,
+                                             (xmlChar *)atom2->valuep);
 	    break;
         case XML_REGEXP_EPSILON:
 	    goto not_determinist;
@@ -2561,9 +2582,14 @@
     int res;
     int transnr, nbTrans;
     xmlRegTransPtr t1;
+    int deep = 1;
 
     if (state == NULL)
 	return(ret);
+
+    if (ctxt->flags & AM_AUTOMATA_RNG)
+        deep = 0;
+
     /*
      * don't recurse on transitions potentially added in the course of
      * the elimination.
@@ -2587,7 +2613,7 @@
 	}
 	if (t1->to != to)
 	    continue;
-	if (xmlFACompareAtoms(t1->atom, atom)) {
+	if (xmlFACompareAtoms(t1->atom, atom, deep)) {
 	    ret = 0;
 	    /* mark the transition as non-deterministic */
 	    t1->nd = 1;
@@ -2611,6 +2637,7 @@
     xmlRegTransPtr t1, t2, last;
     int i;
     int ret = 1;
+    int deep = 1;
 
 #ifdef DEBUG_REGEXP_GRAPH
     printf("xmlFAComputesDeterminism\n");
@@ -2619,6 +2646,9 @@
     if (ctxt->determinist != -1)
 	return(ctxt->determinist);
 
+    if (ctxt->flags & AM_AUTOMATA_RNG)
+        deep = 0;
+
     /*
      * First cleanup the automata removing cancelled transitions
      */
@@ -2646,7 +2676,13 @@
 		    continue;
 		if (t2->atom != NULL) {
 		    if (t1->to == t2->to) {
-			if (xmlFAEqualAtoms(t1->atom, t2->atom))
+                        /*
+                         * Here we use deep because we want to keep the
+                         * transitions which indicate a conflict
+                         */
+			if (xmlFAEqualAtoms(t1->atom, t2->atom, deep) &&
+                            (t1->counter == t2->counter) &&
+                            (t1->count == t2->count))
 			    t2->to = -1; /* eliminated */
 		    }
 		}
@@ -2681,8 +2717,11 @@
 		if (t2->to == -1) /* eliminated */
 		    continue;
 		if (t2->atom != NULL) {
-		    /* not determinist ! */
-		    if (xmlFACompareAtoms(t1->atom, t2->atom)) {
+                    /*
+                     * But here we don't use deep because we want to
+                     * find transitions which indicate a conflict
+                     */
+		    if (xmlFACompareAtoms(t1->atom, t2->atom, 1)) {
 			ret = 0;
 			/* mark the transitions as non-deterministic ones */
 			t1->nd = 1;
@@ -4853,6 +4892,17 @@
 		}
 	    }
 	} else if (ctxt->atom->type == XML_REGEXP_RANGES) {
+            switch (cur) {
+                case 'n':
+                    cur = '\n';
+                    break;
+                case 'r':
+                    cur = '\r';
+                    break;
+                case 't':
+                    cur = '\t';
+                    break;
+            }
 	    xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
 			       XML_REGEXP_CHARVAL, cur, cur, NULL);
 	}
@@ -5470,10 +5520,12 @@
     am->nbStates = comp->nbStates;
     am->states = comp->states;
     am->determinist = -1;
+    am->flags = comp->flags;
     ret = xmlFAComputesDeterminism(am);
     am->atoms = NULL;
     am->states = NULL;
     xmlFreeAutomata(am);
+    comp->determinist = ret;
     return(ret);
 }
 
@@ -5551,6 +5603,7 @@
 	xmlFreeAutomata(ctxt);
 	return(NULL);
     }
+    ctxt->flags = 0;
 
     return(ctxt);
 }
@@ -5569,6 +5622,20 @@
 }
 
 /**
+ * xmlAutomataSetFlags:
+ * @am: an automata
+ * @flags:  a set of internal flags
+ *
+ * Set some flags on the automata
+ */
+void
+xmlAutomataSetFlags(xmlAutomataPtr am, int flags) {
+    if (am == NULL)
+	return;
+    am->flags |= flags;
+}
+
+/**
  * xmlAutomataGetInitState:
  * @am: an automata
  *
@@ -6254,6 +6321,7 @@
     int size;
     int nbElems;
     int nb_nodes;
+    int maxNodes;
     const char *expr;
     const char *cur;
     int nb_cons;
@@ -6283,6 +6351,7 @@
     memset(ret, 0, sizeof(xmlExpCtxt));
     ret->size = size;
     ret->nbElems = 0;
+    ret->maxNodes = maxNodes;
     ret->table = xmlMalloc(size * sizeof(xmlExpNodePtr));
     if (ret->table == NULL) {
         xmlFree(ret);
@@ -6401,7 +6470,7 @@
     if (name != NULL) {
 	value += 30 * (*name);
 	while ((ch = *name++) != 0) {
-	    value = value ^ ((value << 5) + (value >> 3) + (unsigned short)ch);
+	    value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
 	}
     }
     return (value);
@@ -6868,7 +6937,7 @@
 		    return(0);
             if (nb >= len)
 	        return(-2);
-	    list[nb++] = exp->exp_str;
+	    list[nb] = exp->exp_str;
 	    return(1);
         case XML_EXP_COUNT:
 	    exp = exp->exp_left;
@@ -6923,7 +6992,7 @@
 		    return(0);
             if (nb >= len)
 	        return(-2);
-	    list[nb++] = exp->exp_str;
+	    list[nb] = exp->exp_str;
 	    return(1);
         case XML_EXP_COUNT:
 	    exp = exp->exp_left;
diff --git a/xmlsave.c b/xmlsave.c
index 53b23e6..23c3bcc 100644
--- a/xmlsave.c
+++ b/xmlsave.c
@@ -248,7 +248,7 @@
 	    /*
 	     * We assume we have UTF-8 input.
 	     */
-	    if (outend - out < 10) break;
+	    if (outend - out < 11) break;
 
 	    if (*in < 0xC0) {
 		xmlSaveErr(XML_SAVE_NOT_UTF8, NULL, NULL);
@@ -408,6 +408,8 @@
     ret->options = options;
     if (options & XML_SAVE_FORMAT)
         ret->format = 1;
+    else if (options & XML_SAVE_WSNONSIG)
+        ret->format = 2;
 
     return(ret);
 }
@@ -501,32 +503,90 @@
 static int xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur);
 
 /**
+ * xmlOutputBufferWriteWSNonSig:
+ * @ctxt:  The save context
+ * @extra: Number of extra indents to apply to ctxt->level
+ *
+ * Write out formatting for non-significant whitespace output.
+ */
+static void
+xmlOutputBufferWriteWSNonSig(xmlSaveCtxtPtr ctxt, int extra)
+{
+    int i;
+    if ((ctxt == NULL) || (ctxt->buf == NULL))
+        return;
+    xmlOutputBufferWrite(ctxt->buf, 1, "\n");
+    for (i = 0; i < (ctxt->level + extra); i += ctxt->indent_nr) {
+        xmlOutputBufferWrite(ctxt->buf, ctxt->indent_size *
+                ((ctxt->level + extra - i) > ctxt->indent_nr ?
+                 ctxt->indent_nr : (ctxt->level + extra - i)),
+                ctxt->indent);
+    }
+}
+
+/**
  * xmlNsDumpOutput:
  * @buf:  the XML buffer output
  * @cur:  a namespace
+ * @ctxt: the output save context. Optional.
  *
  * Dump a local Namespace definition.
  * Should be called in the context of attributes dumps.
+ * If @ctxt is supplied, @buf should be its buffer.
  */
 static void
-xmlNsDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
+xmlNsDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur, xmlSaveCtxtPtr ctxt) {
     if ((cur == NULL) || (buf == NULL)) return;
     if ((cur->type == XML_LOCAL_NAMESPACE) && (cur->href != NULL)) {
 	if (xmlStrEqual(cur->prefix, BAD_CAST "xml"))
 	    return;
 
+	if (ctxt != NULL && ctxt->format == 2)
+	    xmlOutputBufferWriteWSNonSig(ctxt, 2);
+	else
+	    xmlOutputBufferWrite(buf, 1, " ");
+
         /* Within the context of an element attributes */
 	if (cur->prefix != NULL) {
-	    xmlOutputBufferWrite(buf, 7, " xmlns:");
+	    xmlOutputBufferWrite(buf, 6, "xmlns:");
 	    xmlOutputBufferWriteString(buf, (const char *)cur->prefix);
 	} else
-	    xmlOutputBufferWrite(buf, 6, " xmlns");
+	    xmlOutputBufferWrite(buf, 5, "xmlns");
 	xmlOutputBufferWrite(buf, 1, "=");
 	xmlBufferWriteQuotedString(buf->buffer, cur->href);
     }
 }
 
 /**
+ * xmlNsDumpOutputCtxt
+ * @ctxt: the save context
+ * @cur:  a namespace
+ *
+ * Dump a local Namespace definition to a save context.
+ * Should be called in the context of attribute dumps.
+ */
+static void
+xmlNsDumpOutputCtxt(xmlSaveCtxtPtr ctxt, xmlNsPtr cur) {
+    xmlNsDumpOutput(ctxt->buf, cur, ctxt);
+}
+
+/**
+ * xmlNsListDumpOutputCtxt
+ * @ctxt: the save context
+ * @cur:  the first namespace
+ *
+ * Dump a list of local namespace definitions to a save context.
+ * Should be called in the context of attribute dumps.
+ */
+static void
+xmlNsListDumpOutputCtxt(xmlSaveCtxtPtr ctxt, xmlNsPtr cur) {
+    while (cur != NULL) {
+        xmlNsDumpOutput(ctxt->buf, cur, ctxt);
+	cur = cur->next;
+    }
+}
+
+/**
  * xmlNsListDumpOutput:
  * @buf:  the XML buffer output
  * @cur:  the first namespace
@@ -537,7 +597,7 @@
 void
 xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
     while (cur != NULL) {
-        xmlNsDumpOutput(buf, cur);
+        xmlNsDumpOutput(buf, cur, NULL);
 	cur = cur->next;
     }
 }
@@ -612,7 +672,10 @@
     if (cur == NULL) return;
     buf = ctxt->buf;
     if (buf == NULL) return;
-    xmlOutputBufferWrite(buf, 1, " ");
+    if (ctxt->format == 2)
+        xmlOutputBufferWriteWSNonSig(ctxt, 2);
+    else
+        xmlOutputBufferWrite(buf, 1, " ");
     if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
         xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
 	xmlOutputBufferWrite(buf, 1, ":");
@@ -656,7 +719,7 @@
     if (cur == NULL) return;
     buf = ctxt->buf;
     while (cur != NULL) {
-	if ((ctxt->format) && (xmlIndentTreeOutput) &&
+	if ((ctxt->format == 1) && (xmlIndentTreeOutput) &&
 	    ((cur->type == XML_ELEMENT_NODE) ||
 	     (cur->type == XML_COMMENT_NODE) ||
 	     (cur->type == XML_PI_NODE)))
@@ -665,7 +728,7 @@
 				  ctxt->indent_nr : ctxt->level),
 				 ctxt->indent);
         xmlNodeDumpOutputInternal(ctxt, cur);
-	if (ctxt->format) {
+	if (ctxt->format == 1) {
 	    xmlOutputBufferWrite(buf, 1, "\n");
 	}
 	cur = cur->next;
@@ -690,8 +753,8 @@
 
     xmlInitParser();
 
-    doc = cur->doc; {
-    if (doc != NULL)
+    doc = cur->doc;
+    if (doc != NULL) {
         oldenc = doc->encoding;
 	if (ctxt->encoding != NULL) {
 	    doc->encoding = BAD_CAST ctxt->encoding;
@@ -808,13 +871,18 @@
 	    xmlOutputBufferWrite(buf, 2, "<?");
 	    xmlOutputBufferWriteString(buf, (const char *)cur->name);
 	    if (cur->content != NULL) {
-		xmlOutputBufferWrite(buf, 1, " ");
+	        if (ctxt->format == 2)
+	            xmlOutputBufferWriteWSNonSig(ctxt, 0);
+	        else
+	            xmlOutputBufferWrite(buf, 1, " ");
 		xmlOutputBufferWriteString(buf, (const char *)cur->content);
 	    }
 	    xmlOutputBufferWrite(buf, 2, "?>");
 	} else {
 	    xmlOutputBufferWrite(buf, 2, "<?");
 	    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+	    if (ctxt->format == 2)
+	        xmlOutputBufferWriteWSNonSig(ctxt, 0);
 	    xmlOutputBufferWrite(buf, 2, "?>");
 	}
 	return;
@@ -862,7 +930,7 @@
 	return;
     }
     if (cur->type == XML_NAMESPACE_DECL) {
-	xmlNsDumpOutput(buf, (xmlNsPtr) cur);
+	xmlNsDumpOutputCtxt(ctxt, (xmlNsPtr) cur);
 	return;
     }
 
@@ -887,26 +955,30 @@
 
     xmlOutputBufferWriteString(buf, (const char *)cur->name);
     if (cur->nsDef)
-        xmlNsListDumpOutput(buf, cur->nsDef);
+        xmlNsListDumpOutputCtxt(ctxt, cur->nsDef);
     if (cur->properties != NULL)
         xmlAttrListDumpOutput(ctxt, cur->properties);
 
     if (((cur->type == XML_ELEMENT_NODE) || (cur->content == NULL)) &&
 	(cur->children == NULL) && ((ctxt->options & XML_SAVE_NO_EMPTY) == 0)) {
+        if (ctxt->format == 2)
+            xmlOutputBufferWriteWSNonSig(ctxt, 0);
         xmlOutputBufferWrite(buf, 2, "/>");
 	ctxt->format = format;
 	return;
     }
+    if (ctxt->format == 2)
+        xmlOutputBufferWriteWSNonSig(ctxt, 1);
     xmlOutputBufferWrite(buf, 1, ">");
     if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) {
 	xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape);
     }
     if (cur->children != NULL) {
-	if (ctxt->format) xmlOutputBufferWrite(buf, 1, "\n");
+	if (ctxt->format == 1) xmlOutputBufferWrite(buf, 1, "\n");
 	if (ctxt->level >= 0) ctxt->level++;
 	xmlNodeListDumpOutput(ctxt, cur->children);
 	if (ctxt->level > 0) ctxt->level--;
-	if ((xmlIndentTreeOutput) && (ctxt->format))
+	if ((xmlIndentTreeOutput) && (ctxt->format == 1))
 	    xmlOutputBufferWrite(buf, ctxt->indent_size *
 	                         (ctxt->level > ctxt->indent_nr ? 
 				  ctxt->indent_nr : ctxt->level),
@@ -919,6 +991,8 @@
     }
 
     xmlOutputBufferWriteString(buf, (const char *)cur->name);
+    if (ctxt->format == 2)
+        xmlOutputBufferWriteWSNonSig(ctxt, 0);
     xmlOutputBufferWrite(buf, 1, ">");
     ctxt->format = format;
 }
@@ -976,7 +1050,6 @@
 		cur->encoding = oldenc;
 		return(-1);
 	    }
-	    switched_encoding = 1;
 	}
         if (ctxt->options & XML_SAVE_FORMAT)
 	    htmlDocContentDumpFormatOutput(buf, cur,
@@ -1255,14 +1328,14 @@
     if (cur == NULL) return;
     buf = ctxt->buf;
     while (cur != NULL) {
-	if ((ctxt->format) && (xmlIndentTreeOutput) &&
+	if ((ctxt->format == 1) && (xmlIndentTreeOutput) &&
 	    (cur->type == XML_ELEMENT_NODE))
 	    xmlOutputBufferWrite(buf, ctxt->indent_size *
 	                         (ctxt->level > ctxt->indent_nr ? 
 				  ctxt->indent_nr : ctxt->level),
 				 ctxt->indent);
         xhtmlNodeDumpOutput(ctxt, cur);
-	if (ctxt->format) {
+	if (ctxt->format == 1) {
 	    xmlOutputBufferWrite(buf, 1, "\n");
 	}
 	cur = cur->next;
@@ -1411,7 +1484,7 @@
 
     xmlOutputBufferWriteString(buf, (const char *)cur->name);
     if (cur->nsDef)
-        xmlNsListDumpOutput(buf, cur->nsDef);
+        xmlNsListDumpOutputCtxt(ctxt, cur->nsDef);
     if ((xmlStrEqual(cur->name, BAD_CAST "html") &&
 	(cur->ns == NULL) && (cur->nsDef == NULL))) {
 	/*
@@ -1459,7 +1532,7 @@
 	} else {
 		if (addmeta == 1) {
 			xmlOutputBufferWrite(buf, 1, ">");
-			if (ctxt->format) {
+			if (ctxt->format == 1) {
 				xmlOutputBufferWrite(buf, 1, "\n");
 				if (xmlIndentTreeOutput)
 					xmlOutputBufferWrite(buf, ctxt->indent_size *
@@ -1474,7 +1547,7 @@
 				xmlOutputBufferWrite(buf, 5, "UTF-8");
 			}
 			xmlOutputBufferWrite(buf, 4, "\" />");
-			if (ctxt->format)
+			if (ctxt->format == 1)
 				xmlOutputBufferWrite(buf, 1, "\n");
 		} else {
 			xmlOutputBufferWrite(buf, 1, ">");
@@ -1494,7 +1567,7 @@
     }
     xmlOutputBufferWrite(buf, 1, ">");
 	if (addmeta == 1) {
-		if (ctxt->format) {
+		if (ctxt->format == 1) {
 			xmlOutputBufferWrite(buf, 1, "\n");
 			if (xmlIndentTreeOutput)
 				xmlOutputBufferWrite(buf, ctxt->indent_size *
@@ -1589,13 +1662,13 @@
     if (cur->children != NULL) {
 	int indent = ctxt->format;
 	
-	if (format) xmlOutputBufferWrite(buf, 1, "\n");
+	if (format == 1) xmlOutputBufferWrite(buf, 1, "\n");
 	if (ctxt->level >= 0) ctxt->level++;
 	ctxt->format = format;
 	xhtmlNodeListDumpOutput(ctxt, cur->children);
 	if (ctxt->level > 0) ctxt->level--;
 	ctxt->format = indent;
-	if ((xmlIndentTreeOutput) && (format))
+	if ((xmlIndentTreeOutput) && (format == 1))
 	    xmlOutputBufferWrite(buf, ctxt->indent_size *
 	                         (ctxt->level > ctxt->indent_nr ? 
 				  ctxt->indent_nr : ctxt->level),
@@ -1929,7 +2002,7 @@
             /*
              * We assume we have UTF-8 content.
              */
-            unsigned char tmp[10];
+            unsigned char tmp[12];
             int val = 0, l = 1;
 
             if (base != cur)
@@ -2133,7 +2206,7 @@
     ctxt.doc = doc;
     ctxt.buf = buf;
     ctxt.level = level;
-    ctxt.format = format;
+    ctxt.format = format ? 1 : 0;
     ctxt.encoding = (const xmlChar *) encoding;
     xmlSaveCtxtInit(&ctxt);
     ctxt.options |= XML_SAVE_AS_XML;
@@ -2219,7 +2292,7 @@
     ctxt.doc = out_doc;
     ctxt.buf = out_buff;
     ctxt.level = 0;
-    ctxt.format = format;
+    ctxt.format = format ? 1 : 0;
     ctxt.encoding = (const xmlChar *) txt_encoding;
     xmlSaveCtxtInit(&ctxt);
     ctxt.options |= XML_SAVE_AS_XML;
@@ -2338,7 +2411,7 @@
     ctxt.doc = cur;
     ctxt.buf = buf;
     ctxt.level = 0;
-    ctxt.format = format;
+    ctxt.format = format ? 1 : 0;
     ctxt.encoding = (const xmlChar *) encoding;
     xmlSaveCtxtInit(&ctxt);
     ctxt.options |= XML_SAVE_AS_XML;
@@ -2428,7 +2501,7 @@
     ctxt.doc = cur;
     ctxt.buf = buf;
     ctxt.level = 0;
-    ctxt.format = format;
+    ctxt.format = format ? 1 : 0;
     ctxt.encoding = (const xmlChar *) encoding;
     xmlSaveCtxtInit(&ctxt);
     ctxt.options |= XML_SAVE_AS_XML;
@@ -2483,7 +2556,7 @@
     ctxt.doc = cur;
     ctxt.buf = buf;
     ctxt.level = 0;
-    ctxt.format = format;
+    ctxt.format = format ? 1 : 0;
     ctxt.encoding = (const xmlChar *) encoding;
     xmlSaveCtxtInit(&ctxt);
     ctxt.options |= XML_SAVE_AS_XML;
diff --git a/xmlschemas.c b/xmlschemas.c
index 47451b1..ddb31d6 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -6797,7 +6797,7 @@
 		    tmp->next = NULL;
 		    if (wildc->nsSet == NULL)
 			wildc->nsSet = tmp;
-		    else
+		    else if (lastNs != NULL)
 			lastNs->next = tmp;
 		    lastNs = tmp;
 		}
@@ -10343,27 +10343,39 @@
 
     /* Did we already fetch the doc? */
     if (bkt != NULL) {
-	/* TODO: The following nasty cases will produce an error. */
 	if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
-	    /* We included/redefined and then try to import a schema. */
+	    /*
+	    * We included/redefined and then try to import a schema,
+	    * but the new location provided for import was different.
+	    */
 	    if (schemaLocation == NULL)
 		schemaLocation = BAD_CAST "in_memory_buffer";
-	    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
-		invokingNode, NULL,
-		"The schema document '%s' cannot be imported, since "
-		"it was already included or redefined",
-		schemaLocation, NULL);
-	    goto exit;
+	    if (!xmlStrEqual(schemaLocation,
+		bkt->schemaLocation)) {
+		xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
+		    invokingNode, NULL,
+		    "The schema document '%s' cannot be imported, since "
+		    "it was already included or redefined",
+		    schemaLocation, NULL);
+		goto exit;
+	    }
 	} else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
-	    /* We imported and then try to include/redefine a schema. */
+	    /*
+	    * We imported and then try to include/redefine a schema,
+	    * but the new location provided for the include/redefine
+	    * was different.
+	    */
 	    if (schemaLocation == NULL)
 		schemaLocation = BAD_CAST "in_memory_buffer";
-	    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
-		invokingNode, NULL,
-		"The schema document '%s' cannot be included or "
-		"redefined, since it was already imported",
-		schemaLocation, NULL);
-	    goto exit;
+	    if (!xmlStrEqual(schemaLocation,
+		bkt->schemaLocation)) {
+		xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
+		    invokingNode, NULL,
+		    "The schema document '%s' cannot be included or "
+		    "redefined, since it was already imported",
+		    schemaLocation, NULL);
+		goto exit;
+	    }
 	}
     }
 
@@ -10519,9 +10531,9 @@
 	    /* Parse from memory buffer. */
 	    doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
 		NULL, NULL, SCHEMAS_PARSE_OPTIONS);
-	    schemaLocation = xmlStrdup(BAD_CAST "in_memory_buffer");
+	    schemaLocation = BAD_CAST "in_memory_buffer";
 	    if (doc != NULL)
-		doc->URL = schemaLocation;
+		doc->URL = xmlStrdup(schemaLocation);
 	}
 	/*
 	* For <import>:
@@ -11027,14 +11039,15 @@
 	    */
 	    isChameleon = 1;
 	    if (bucket->parsed &&
-		(bucket->targetNamespace != pctxt->targetNamespace)) {
-		/*
-		* This is a sanity check, I dunno yet if this can happen.
-		*/
-		PERROR_INT("xmlSchemaParseIncludeOrRedefine",
-		    "trying to use an already parsed schema for a "
-		    "different targetNamespace");
-		return(-1);
+		bucket->origTargetNamespace != NULL) {
+		xmlSchemaCustomErr(ACTXT_CAST pctxt,
+		    XML_SCHEMAP_SRC_INCLUDE,
+		    node, NULL,
+		    "The target namespace of the included/redefined schema "
+		    "'%s' has to be absent or the same as the "
+		    "including/redefining schema's target namespace",
+		    schemaLocation, NULL);
+		goto exit_error;
 	    }
 	    bucket->targetNamespace = pctxt->targetNamespace;
 	}
@@ -12512,7 +12525,12 @@
  *									*
  ************************************************************************/
 
-static void
+/**
+ * xmlSchemaBuildContentModelForSubstGroup:
+ *
+ * Returns 1 if nillable, 0 otherwise
+ */
+static int
 xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
 	xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
 {
@@ -12520,6 +12538,7 @@
     xmlSchemaElementPtr elemDecl, member;
     xmlSchemaSubstGroupPtr substGroup;
     int i;
+    int ret = 0;
 
     elemDecl = (xmlSchemaElementPtr) particle->children;
     /*
@@ -12535,7 +12554,7 @@
 	    "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
 	    "declaration is marked having a subst. group but none "
 	    "available.\n", elemDecl->name, NULL);
-	return;
+	return(0);
     }
     if (counter >= 0) {
 	/*
@@ -12615,21 +12634,31 @@
 	xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
 	xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
     }
-    if (particle->minOccurs == 0)
+    if (particle->minOccurs == 0) {
 	xmlAutomataNewEpsilon(pctxt->am, start, end);
+        ret = 1;
+    }
     pctxt->state = end;
+    return(ret);
 }
 
-static void
+/**
+ * xmlSchemaBuildContentModelForElement:
+ *
+ * Returns 1 if nillable, 0 otherwise
+ */
+static int
 xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
 				     xmlSchemaParticlePtr particle)
 {
+    int ret = 0;
+
     if (((xmlSchemaElementPtr) particle->children)->flags &
 	XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
 	/*
 	* Substitution groups.
 	*/
-	xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
+	ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
     } else {
 	xmlSchemaElementPtr elemDecl;
 	xmlAutomataStatePtr start;
@@ -12637,7 +12666,7 @@
 	elemDecl = (xmlSchemaElementPtr) particle->children;
 
 	if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
-	    return;
+	    return(0);
 	if (particle->maxOccurs == 1) {
 	    start = ctxt->state;
 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
@@ -12665,9 +12694,12 @@
 	    ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
 		NULL, counter);
 	}
-	if (particle->minOccurs == 0)
+	if (particle->minOccurs == 0) {
 	    xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
+            ret = 1;
+        }
     }
+    return(ret);
 }
 
 /**
@@ -12678,21 +12710,24 @@
  *
  * Create the automaton for the {content type} of a complex type.
  *
+ * Returns 1 if the content is nillable, 0 otherwise
  */
-static void
+static int
 xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
 			    xmlSchemaParticlePtr particle)
 {
+    int ret = 0, tmp2;
+
     if (particle == NULL) {
 	PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
-	return;
+	return(1);
     }
     if (particle->children == NULL) {
 	/*
 	* Just return in this case. A missing "term" of the particle
 	* might arise due to an invalid "term" component.
 	*/
-	return;
+	return(1);
     }
 
     switch (particle->children->type) {
@@ -12744,7 +12779,8 @@
 		int counter;
 		xmlAutomataStatePtr hop;
 		int maxOccurs =
-		    particle->maxOccurs == UNBOUNDED ? UNBOUNDED : particle->maxOccurs - 1;
+		    particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
+                                           particle->maxOccurs - 1;
 		int minOccurs =
 		    particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
 
@@ -12779,243 +12815,273 @@
 	    }
 	    if (particle->minOccurs == 0) {
 		xmlAutomataNewEpsilon(pctxt->am, start, end);
+                ret = 1;
 	    }
 	    pctxt->state = end;
             break;
 	}
         case XML_SCHEMA_TYPE_ELEMENT:
-	    xmlSchemaBuildContentModelForElement(pctxt, particle);
+	    ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
 	    break;
         case XML_SCHEMA_TYPE_SEQUENCE:{
-                xmlSchemaTreeItemPtr sub;
+            xmlSchemaTreeItemPtr sub;
 
-                /*
-                 * If max and min occurances are default (1) then
-                 * simply iterate over the particles of the <sequence>.
-                 */
-                if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
-                    sub = particle->children->children;
-                    while (sub != NULL) {
-                        xmlSchemaBuildAContentModel(pctxt,
-			    (xmlSchemaParticlePtr) sub);
-                        sub = sub->next;
-                    }
-                } else {
-                    xmlAutomataStatePtr oldstate = pctxt->state;
+            ret = 1;
+            /*
+             * If max and min occurances are default (1) then
+             * simply iterate over the particles of the <sequence>.
+             */
+            if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
+                sub = particle->children->children;
 
-                    if (particle->maxOccurs >= UNBOUNDED) {
-                        if (particle->minOccurs > 1) {
-                            xmlAutomataStatePtr tmp;
-                            int counter;
+                while (sub != NULL) {
+                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
+                                        (xmlSchemaParticlePtr) sub);
+                    if (tmp2 != 1) ret = 0;
+                    sub = sub->next;
+                }
+            } else {
+                xmlAutomataStatePtr oldstate = pctxt->state;
 
-                            pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
-				oldstate, NULL);
-                            oldstate = pctxt->state;
-
-                            counter = xmlAutomataNewCounter(pctxt->am,
-				particle->minOccurs - 1, UNBOUNDED);
-
-                            sub = particle->children->children;
-                            while (sub != NULL) {
-                                xmlSchemaBuildAContentModel(pctxt,
-				    (xmlSchemaParticlePtr) sub);
-                                sub = sub->next;
-                            }
-                            tmp = pctxt->state;
-                            xmlAutomataNewCountedTrans(pctxt->am, tmp,
-                                                       oldstate, counter);
-                            pctxt->state =
-                                xmlAutomataNewCounterTrans(pctxt->am, tmp,
-                                                           NULL, counter);
-
-                        } else {
-                            pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
-				oldstate, NULL);
-                            oldstate = pctxt->state;
-
-			    sub = particle->children->children;
-                            while (sub != NULL) {
-                                xmlSchemaBuildAContentModel(pctxt,
-				    (xmlSchemaParticlePtr) sub);
-                                sub = sub->next;
-                            }
-                            xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
-                                                  oldstate);
-			    /*
-			     * epsilon needed to block previous trans from
-			     * being allowed to enter back from another
-			     * construct
-			     */
-			    pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
-						pctxt->state, NULL);
-                            if (particle->minOccurs == 0) {
-                                xmlAutomataNewEpsilon(pctxt->am,
-				    oldstate, pctxt->state);
-                            }
-                        }
-                    } else if ((particle->maxOccurs > 1)
-                               || (particle->minOccurs > 1)) {
+                if (particle->maxOccurs >= UNBOUNDED) {
+                    if (particle->minOccurs > 1) {
                         xmlAutomataStatePtr tmp;
                         int counter;
 
                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
-			    oldstate, NULL);
+                            oldstate, NULL);
                         oldstate = pctxt->state;
 
                         counter = xmlAutomataNewCounter(pctxt->am,
-			    particle->minOccurs - 1,
-			    particle->maxOccurs - 1);
+                            particle->minOccurs - 1, UNBOUNDED);
 
                         sub = particle->children->children;
                         while (sub != NULL) {
-                            xmlSchemaBuildAContentModel(pctxt,
-				(xmlSchemaParticlePtr) sub);
+                            tmp2 = xmlSchemaBuildAContentModel(pctxt,
+                                            (xmlSchemaParticlePtr) sub);
+                            if (tmp2 != 1) ret = 0;
                             sub = sub->next;
                         }
                         tmp = pctxt->state;
-                        xmlAutomataNewCountedTrans(pctxt->am,
-			    tmp, oldstate, counter);
+                        xmlAutomataNewCountedTrans(pctxt->am, tmp,
+                                                   oldstate, counter);
                         pctxt->state =
-                            xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
-                                                       counter);
-                        if (particle->minOccurs == 0) {
+                            xmlAutomataNewCounterTrans(pctxt->am, tmp,
+                                                       NULL, counter);
+                        if (ret == 1)
                             xmlAutomataNewEpsilon(pctxt->am,
-				oldstate, pctxt->state);
-                        }
+                                                oldstate, pctxt->state);
+
                     } else {
+                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
+                            oldstate, NULL);
+                        oldstate = pctxt->state;
+
                         sub = particle->children->children;
                         while (sub != NULL) {
-                            xmlSchemaBuildAContentModel(pctxt,
-				(xmlSchemaParticlePtr) sub);
+                            tmp2 = xmlSchemaBuildAContentModel(pctxt,
+                                        (xmlSchemaParticlePtr) sub);
+                            if (tmp2 != 1) ret = 0;
                             sub = sub->next;
                         }
+                        xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
+                                              oldstate);
+                        /*
+                         * epsilon needed to block previous trans from
+                         * being allowed to enter back from another
+                         * construct
+                         */
+                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
+                                            pctxt->state, NULL);
                         if (particle->minOccurs == 0) {
-                            xmlAutomataNewEpsilon(pctxt->am, oldstate,
-                                                  pctxt->state);
+                            xmlAutomataNewEpsilon(pctxt->am,
+                                oldstate, pctxt->state);
+                            ret = 1;
                         }
                     }
-                }
-                break;
-            }
-        case XML_SCHEMA_TYPE_CHOICE:{
-                xmlSchemaTreeItemPtr sub;
-                xmlAutomataStatePtr start, end;
+                } else if ((particle->maxOccurs > 1)
+                           || (particle->minOccurs > 1)) {
+                    xmlAutomataStatePtr tmp;
+                    int counter;
 
-                start = pctxt->state;
-                end = xmlAutomataNewState(pctxt->am);
+                    pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
+                        oldstate, NULL);
+                    oldstate = pctxt->state;
 
-                /*
-                 * iterate over the subtypes and remerge the end with an
-                 * epsilon transition
-                 */
-                if (particle->maxOccurs == 1) {
-		    sub = particle->children->children;
+                    counter = xmlAutomataNewCounter(pctxt->am,
+                        particle->minOccurs - 1,
+                        particle->maxOccurs - 1);
+
+                    sub = particle->children->children;
                     while (sub != NULL) {
-                        pctxt->state = start;
-                        xmlSchemaBuildAContentModel(pctxt,
-			    (xmlSchemaParticlePtr) sub);
-                        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
+                        tmp2 = xmlSchemaBuildAContentModel(pctxt,
+                                        (xmlSchemaParticlePtr) sub);
+                        if (tmp2 != 1) ret = 0;
                         sub = sub->next;
                     }
+                    tmp = pctxt->state;
+                    xmlAutomataNewCountedTrans(pctxt->am,
+                        tmp, oldstate, counter);
+                    pctxt->state =
+                        xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
+                                                   counter);
+                    if ((particle->minOccurs == 0) || (ret == 1)) {
+                        xmlAutomataNewEpsilon(pctxt->am,
+                                            oldstate, pctxt->state);
+                        ret = 1;
+                    }
                 } else {
-                    int counter;
-                    xmlAutomataStatePtr hop, base;
-                    int maxOccurs = particle->maxOccurs == UNBOUNDED ?
-                        UNBOUNDED : particle->maxOccurs - 1;
-                    int minOccurs =
-                        particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
-
-                    /*
-                     * use a counter to keep track of the number of transtions
-                     * which went through the choice.
-                     */
-                    counter =
-                        xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
-                    hop = xmlAutomataNewState(pctxt->am);
-                    base = xmlAutomataNewState(pctxt->am);
-
-		    sub = particle->children->children;
+                    sub = particle->children->children;
                     while (sub != NULL) {
-                        pctxt->state = base;
-                        xmlSchemaBuildAContentModel(pctxt,
-			    (xmlSchemaParticlePtr) sub);
-                        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
+                        tmp2 = xmlSchemaBuildAContentModel(pctxt,
+                                        (xmlSchemaParticlePtr) sub);
+                        if (tmp2 != 1) ret = 0;
                         sub = sub->next;
                     }
-                    xmlAutomataNewEpsilon(pctxt->am, start, base);
-		    xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
-                    xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
+                    if (particle->minOccurs == 0) {
+                        xmlAutomataNewEpsilon(pctxt->am, oldstate,
+                                              pctxt->state);
+                        ret = 1;
+                    }
                 }
-                if (particle->minOccurs == 0) {
-                    xmlAutomataNewEpsilon(pctxt->am, start, end);
-                }
-                pctxt->state = end;
-                break;
             }
-        case XML_SCHEMA_TYPE_ALL:{
-                xmlAutomataStatePtr start;
-		xmlSchemaParticlePtr sub;
-		xmlSchemaElementPtr elemDecl;
-                int lax;
+            break;
+        }
+        case XML_SCHEMA_TYPE_CHOICE:{
+            xmlSchemaTreeItemPtr sub;
+            xmlAutomataStatePtr start, end;
 
-		sub = (xmlSchemaParticlePtr) particle->children->children;
-                if (sub == NULL)
-                    break;
-                start = pctxt->state;
+            ret = 0;
+            start = pctxt->state;
+            end = xmlAutomataNewState(pctxt->am);
+
+            /*
+             * iterate over the subtypes and remerge the end with an
+             * epsilon transition
+             */
+            if (particle->maxOccurs == 1) {
+                sub = particle->children->children;
                 while (sub != NULL) {
                     pctxt->state = start;
-
-		    elemDecl = (xmlSchemaElementPtr) sub->children;
-		    if (elemDecl == NULL) {
-			PERROR_INT("xmlSchemaBuildAContentModel",
-			    "<element> particle has no term");
-			return;
-		    };
-		    /*
-		    * NOTE: The {max occurs} of all the particles in the
-		    * {particles} of the group must be 0 or 1; this is
-		    * already ensured during the parse of the content of
-		    * <all>.
-		    */
-		    if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
-			int counter;
-
-		        /*
-			 * This is an abstract group, we need to share
-			 * the same counter for all the element transitions
-			 * derived from the group
-			 */
-			counter = xmlAutomataNewCounter(pctxt->am,
-			                   sub->minOccurs, sub->maxOccurs);
-			xmlSchemaBuildContentModelForSubstGroup(pctxt,
-					   sub, counter, pctxt->state);
-		    } else {
-			if ((sub->minOccurs == 1) &&
-			    (sub->maxOccurs == 1)) {
-			    xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
-						    pctxt->state,
-						    elemDecl->name,
-						    elemDecl->targetNamespace,
-						    1, 1, elemDecl);
-			} else if ((sub->minOccurs == 0) &&
-			    (sub->maxOccurs == 1)) {
-
-			    xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
-						     pctxt->state,
-						     elemDecl->name,
-						     elemDecl->targetNamespace,
-						     0,
-						     1,
-						     elemDecl);
-			}
-		    }
-                    sub = (xmlSchemaParticlePtr) sub->next;
+                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
+                                        (xmlSchemaParticlePtr) sub);
+                    if (tmp2 == 1) ret = 1;
+                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
+                    sub = sub->next;
                 }
-                lax = particle->minOccurs == 0;
-                pctxt->state =
-                    xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, lax);
-                break;
+            } else {
+                int counter;
+                xmlAutomataStatePtr hop, base;
+                int maxOccurs = particle->maxOccurs == UNBOUNDED ?
+                    UNBOUNDED : particle->maxOccurs - 1;
+                int minOccurs =
+                    particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
+
+                /*
+                 * use a counter to keep track of the number of transtions
+                 * which went through the choice.
+                 */
+                counter =
+                    xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
+                hop = xmlAutomataNewState(pctxt->am);
+                base = xmlAutomataNewState(pctxt->am);
+
+                sub = particle->children->children;
+                while (sub != NULL) {
+                    pctxt->state = base;
+                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
+                                        (xmlSchemaParticlePtr) sub);
+                    if (tmp2 == 1) ret = 1;
+                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
+                    sub = sub->next;
+                }
+                xmlAutomataNewEpsilon(pctxt->am, start, base);
+                xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
+                xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
+                if (ret == 1)
+                    xmlAutomataNewEpsilon(pctxt->am, base, end);
             }
+            if (particle->minOccurs == 0) {
+                xmlAutomataNewEpsilon(pctxt->am, start, end);
+                ret = 1;
+            }
+            pctxt->state = end;
+            break;
+        }
+        case XML_SCHEMA_TYPE_ALL:{
+            xmlAutomataStatePtr start, tmp;
+            xmlSchemaParticlePtr sub;
+            xmlSchemaElementPtr elemDecl;
+
+            ret = 1;
+
+            sub = (xmlSchemaParticlePtr) particle->children->children;
+            if (sub == NULL)
+                break;
+
+            ret = 0;
+
+            start = pctxt->state;
+            tmp = xmlAutomataNewState(pctxt->am);
+            xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
+            pctxt->state = tmp;
+            while (sub != NULL) {
+                pctxt->state = tmp;
+
+                elemDecl = (xmlSchemaElementPtr) sub->children;
+                if (elemDecl == NULL) {
+                    PERROR_INT("xmlSchemaBuildAContentModel",
+                        "<element> particle has no term");
+                    return(ret);
+                };
+                /*
+                * NOTE: The {max occurs} of all the particles in the
+                * {particles} of the group must be 0 or 1; this is
+                * already ensured during the parse of the content of
+                * <all>.
+                */
+                if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
+                    int counter;
+
+                    /*
+                     * This is an abstract group, we need to share
+                     * the same counter for all the element transitions
+                     * derived from the group
+                     */
+                    counter = xmlAutomataNewCounter(pctxt->am,
+                                       sub->minOccurs, sub->maxOccurs);
+                    xmlSchemaBuildContentModelForSubstGroup(pctxt,
+                                       sub, counter, pctxt->state);
+                } else {
+                    if ((sub->minOccurs == 1) &&
+                        (sub->maxOccurs == 1)) {
+                        xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
+                                                pctxt->state,
+                                                elemDecl->name,
+                                                elemDecl->targetNamespace,
+                                                1, 1, elemDecl);
+                    } else if ((sub->minOccurs == 0) &&
+                        (sub->maxOccurs == 1)) {
+
+                        xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
+                                                 pctxt->state,
+                                                 elemDecl->name,
+                                                 elemDecl->targetNamespace,
+                                                 0,
+                                                 1,
+                                                 elemDecl);
+                    }
+                }
+                sub = (xmlSchemaParticlePtr) sub->next;
+            }
+            pctxt->state =
+                xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
+            if (particle->minOccurs == 0) {
+                xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
+                ret = 1;
+            }
+            break;
+        }
 	case XML_SCHEMA_TYPE_GROUP:
 	    /*
 	    * If we hit a model group definition, then this means that
@@ -13024,14 +13090,16 @@
 	    * TODO: But the group should be substituted and not occur at
 	    * all in the content model at this point. Fix this.
 	    */
+            ret = 1;
 	    break;
         default:
 	    xmlSchemaInternalErr2(ACTXT_CAST pctxt,
 		"xmlSchemaBuildAContentModel",
 		"found unexpected term of type '%s' in content model",
 		WXS_ITEM_TYPE_NAME(particle->children), NULL);
-            return;
+            return(ret);
     }
+    return(ret);
 }
 
 /**
@@ -15088,9 +15156,10 @@
 	FREE_AND_NULL(str)
 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
     }
-    if ( (WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
-	 (WXS_IS_RESTRICTION(type) == 0) &&
-	 (! WXS_IS_ANY_SIMPLE_TYPE(baseType))) {
+    if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
+	(WXS_IS_RESTRICTION(type) == 0) &&
+	((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
+         (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
 	xmlSchemaPCustomErr(ctxt,
 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
 	    WXS_BASIC_CAST type, NULL,
@@ -15567,7 +15636,8 @@
 			    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
 			}
 			member = member->next;
-			baseMember = baseMember->next;
+                        if (baseMember != NULL)
+                            baseMember = baseMember->next;
 		    }
 		}
 	    }
@@ -17289,7 +17359,7 @@
 	flength = bflength;
     if (flength) {
 	if (! fminlen)
-	    flength = bflength;
+	    fminlen = bfminlen;
 	if (fminlen) {
 	    /* (1.1) length >= minLength */
 	    res = xmlSchemaCompareValues(flength->val, fminlen->val);
@@ -23653,12 +23723,14 @@
 		parBind->dupls = bind->dupls;
 		bind->dupls = NULL;
 	    }
-	    if (*parTable == NULL)
-		*parTable = parBind;
-	    else {
-		parBind->next = *parTable;
-		*parTable = parBind;
-	    }
+            if (parTable != NULL) {
+                if (*parTable == NULL)
+                    *parTable = parBind;
+                else {
+                    parBind->next = *parTable;
+                    *parTable = parBind;
+                }
+            }
 	}
 
 next_binding:
@@ -24461,10 +24533,10 @@
 		    /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
 		    if (valNeeded)
 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
-			    value, &val, NULL);
+			    value, &val, node);
 		    else
 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
-			    value, NULL, NULL);
+			    value, NULL, node);
 		    break;
 	    }
 	} else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
@@ -25222,7 +25294,6 @@
 
     if (vctxt->nbAttrInfos == 0)
 	return (0);
-    nbUses = vctxt->nbAttrInfos;
     /*
     * Validate against the wildcard.
     */
@@ -25313,16 +25384,18 @@
 			* whose {attribute declaration}'s {type definition}
 			* is or is derived from ID."
 			*/
-			for (j = 0; j < attrUseList->nbItems; j++) {
-			    if (xmlSchemaIsDerivedFromBuiltInType(
-				WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
-				XML_SCHEMAS_ID)) {
-				/* URGENT VAL TODO: implement */
-				iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
-				TODO
-				break;
-			    }
-			}
+                        if (attrUseList != NULL) {
+                            for (j = 0; j < attrUseList->nbItems; j++) {
+                                if (xmlSchemaIsDerivedFromBuiltInType(
+                                    WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
+                                    XML_SCHEMAS_ID)) {
+                                    /* URGENT VAL TODO: implement */
+                            iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
+                                    TODO
+                                    break;
+                                }
+                            }
+                        }
 		    }
 		} else if (type->attributeWildcard->processContents ==
 		    XML_SCHEMAS_ANY_LAX) {
@@ -26739,6 +26812,11 @@
 	    vctxt->skipDepth = 0;
 	    return(ret);
 	}
+        /*
+         * Augment the IDC definitions for the main schema and all imported ones
+         * NOTE: main schema is the first in the imported list
+         */
+        xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
     }
     if (vctxt->depth > 0) {
 	/*
diff --git a/xmlschemastypes.c b/xmlschemastypes.c
index 0d967d0..834b261 100644
--- a/xmlschemastypes.c
+++ b/xmlschemastypes.c
@@ -2389,9 +2389,11 @@
 		normOnTheFly);
             break;
         case XML_SCHEMAS_FLOAT:
-        case XML_SCHEMAS_DOUBLE:{
+        case XML_SCHEMAS_DOUBLE: {
                 const xmlChar *cur = value;
                 int neg = 0;
+                int digits_before = 0;
+                int digits_after = 0;
 
 		if (normOnTheFly)
 		    while IS_WSP_BLANK_CH(*cur) cur++;
@@ -2464,12 +2466,17 @@
                     goto return1;
                 while ((*cur >= '0') && (*cur <= '9')) {
                     cur++;
+                    digits_before++;
                 }
                 if (*cur == '.') {
                     cur++;
-                    while ((*cur >= '0') && (*cur <= '9'))
+                    while ((*cur >= '0') && (*cur <= '9')) {
                         cur++;
+                        digits_after++;
+                    }
                 }
+                if ((digits_before == 0) && (digits_after == 0))
+                    goto return1;
                 if ((*cur == 'e') || (*cur == 'E')) {
                     cur++;
                     if ((*cur == '-') || (*cur == '+'))
@@ -2899,12 +2906,23 @@
         case XML_SCHEMAS_ANYURI:{		
                 if (*value != 0) {
 		    xmlURIPtr uri;
+		    xmlChar *tmpval, *cur;
 		    if (normOnTheFly) {		    
 			norm = xmlSchemaCollapseString(value);
 			if (norm != NULL)
 			    value = norm;
 		    }
-                    uri = xmlParseURI((const char *) value);
+		    tmpval = xmlStrdup(value);
+		    for (cur = tmpval; *cur; ++cur) {
+			if (*cur < 32 || *cur >= 127 || *cur == ' ' ||
+			    *cur == '<' || *cur == '>' || *cur == '"' ||
+			    *cur == '{' || *cur == '}' || *cur == '|' ||
+			    *cur == '\\' || *cur == '^' || *cur == '`' ||
+			    *cur == '\'')
+			    *cur = '_';
+		    }
+                    uri = xmlParseURI((const char *) tmpval);
+		    xmlFree(tmpval);
                     if (uri == NULL)
                         goto return1;
                     xmlFreeURI(uri);
@@ -3551,8 +3569,8 @@
 
     /* seconds */
     sec = x->value.dur.sec - y->value.dur.sec;
-    carry = (long)sec / SECS_PER_DAY;
-    sec -= (double)(carry * SECS_PER_DAY);
+    carry = (long)(sec / SECS_PER_DAY);
+    sec -= ((double)carry) * SECS_PER_DAY;
 
     /* days */
     day = x->value.dur.day - y->value.dur.day + carry;
diff --git a/xmlstring.c b/xmlstring.c
index 4f3b373..910f244 100644
--- a/xmlstring.c
+++ b/xmlstring.c
@@ -366,7 +366,7 @@
  */
 
 const xmlChar *
-xmlStrcasestr(const xmlChar *str, xmlChar *val) {
+xmlStrcasestr(const xmlChar *str, const xmlChar *val) {
     int n;
     
     if (str == NULL) return(NULL);
diff --git a/xmlwriter.c b/xmlwriter.c
index f0eef34..11b15e0 100644
--- a/xmlwriter.c
+++ b/xmlwriter.c
@@ -242,8 +242,8 @@
 
     out = xmlOutputBufferCreateFilename(uri, NULL, compression);
     if (out == NULL) {
-        xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
-                        "xmlNewTextWriterFilename : out of memory!\n");
+        xmlWriterErrMsg(NULL, XML_IO_EIO,
+                        "xmlNewTextWriterFilename : cannot open uri\n");
         return NULL;
     }
 
@@ -370,7 +370,7 @@
     ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
     if (ctxt == NULL) {
         xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
-                        "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
+                "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
         return NULL;
     }
     /*
@@ -389,8 +389,10 @@
 
     ret = xmlNewTextWriterPushParser(ctxt, compression);
     if (ret == NULL) {
+        xmlFreeDoc(ctxt->myDoc);
+        xmlFreeParserCtxt(ctxt);
         xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
-                        "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
+                "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
         return NULL;
     }
 
@@ -898,8 +900,8 @@
     }
 
     buf = xmlTextWriterVSprintf(format, argptr);
-    if (buf == 0)
-        return 0;
+    if (buf == NULL)
+        return -1;
 
     rc = xmlTextWriterWriteComment(writer, buf);
 
@@ -1323,8 +1325,8 @@
         return -1;
 
     buf = xmlTextWriterVSprintf(format, argptr);
-    if (buf == 0)
-        return 0;
+    if (buf == NULL)
+        return -1;
 
     rc = xmlTextWriterWriteRaw(writer, buf);
 
@@ -1452,8 +1454,8 @@
         return -1;
 
     buf = xmlTextWriterVSprintf(format, argptr);
-    if (buf == 0)
-        return 0;
+    if (buf == NULL)
+        return -1;
 
     rc = xmlTextWriterWriteString(writer, buf);
 
@@ -1510,12 +1512,13 @@
 
     if (buf != NULL) {
         count = xmlTextWriterWriteRaw(writer, buf);
-        if (count < 0)
-            return -1;
-        sum += count;
 
         if (buf != content)     /* buf was allocated by us, so free it */
             xmlFree(buf);
+
+        if (count < 0)
+            return -1;
+        sum += count;
     }
 
     return sum;
@@ -1997,8 +2000,8 @@
         return -1;
 
     buf = xmlTextWriterVSprintf(format, argptr);
-    if (buf == 0)
-        return 0;
+    if (buf == NULL)
+        return -1;
 
     rc = xmlTextWriterWriteAttribute(writer, name, buf);
 
@@ -2099,8 +2102,8 @@
         return -1;
 
     buf = xmlTextWriterVSprintf(format, argptr);
-    if (buf == 0)
-        return 0;
+    if (buf == NULL)
+        return -1;
 
     rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
                                        buf);
@@ -2200,8 +2203,8 @@
         return -1;
 
     buf = xmlTextWriterVSprintf(format, argptr);
-    if (buf == 0)
-        return 0;
+    if (buf == NULL)
+        return -1;
 
     rc = xmlTextWriterWriteElement(writer, name, buf);
 
@@ -2302,8 +2305,8 @@
         return -1;
 
     buf = xmlTextWriterVSprintf(format, argptr);
-    if (buf == 0)
-        return 0;
+    if (buf == NULL)
+        return -1;
 
     rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
                                      buf);
@@ -2551,8 +2554,8 @@
         return -1;
 
     buf = xmlTextWriterVSprintf(format, argptr);
-    if (buf == 0)
-        return 0;
+    if (buf == NULL)
+        return -1;
 
     rc = xmlTextWriterWritePI(writer, target, buf);
 
@@ -2764,8 +2767,8 @@
         return -1;
 
     buf = xmlTextWriterVSprintf(format, argptr);
-    if (buf == 0)
-        return 0;
+    if (buf == NULL)
+        return -1;
 
     rc = xmlTextWriterWriteCDATA(writer, buf);
 
@@ -3082,8 +3085,8 @@
         return -1;
 
     buf = xmlTextWriterVSprintf(format, argptr);
-    if (buf == 0)
-        return 0;
+    if (buf == NULL)
+        return -1;
 
     rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
 
@@ -3320,8 +3323,8 @@
         return -1;
 
     buf = xmlTextWriterVSprintf(format, argptr);
-    if (buf == 0)
-        return 0;
+    if (buf == NULL)
+        return -1;
 
     rc = xmlTextWriterWriteDTDElement(writer, name, buf);
 
@@ -3557,8 +3560,8 @@
         return -1;
 
     buf = xmlTextWriterVSprintf(format, argptr);
-    if (buf == 0)
-        return 0;
+    if (buf == NULL)
+        return -1;
 
     rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
 
@@ -3819,8 +3822,8 @@
         return -1;
 
     buf = xmlTextWriterVSprintf(format, argptr);
-    if (buf == 0)
-        return 0;
+    if (buf == NULL)
+        return -1;
 
     rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
 
diff --git a/xpath.c b/xpath.c
index 4783c0e..d9d902c 100644
--- a/xpath.c
+++ b/xpath.c
@@ -252,6 +252,7 @@
     "Encoding error\n",
     "Char out of XML range\n",
     "Invalid or incomplete context\n",
+    "Stack usage errror\n",
     "?? Unknown error ??\n"	/* Must be last in the list! */
 };
 #define MAXERRNO ((int)(sizeof(xmlXPathErrorMessages) /	\
@@ -2398,6 +2399,42 @@
  ************************************************************************/
 
 /**
+ * xmlXPathSetFrame:
+ * @ctxt: an XPath parser context
+ *
+ * Set the callee evaluation frame
+ *
+ * Returns the previous frame value to be restored once done
+ */
+static int
+xmlXPathSetFrame(xmlXPathParserContextPtr ctxt) {
+    int ret;
+
+    if (ctxt == NULL)
+        return(0);
+    ret = ctxt->valueFrame;
+    ctxt->valueFrame = ctxt->valueNr;
+    return(ret);
+}
+
+/**
+ * xmlXPathPopFrame:
+ * @ctxt: an XPath parser context
+ * @frame: the previous frame value
+ *
+ * Remove the callee evaluation frame
+ */
+static void
+xmlXPathPopFrame(xmlXPathParserContextPtr ctxt, int frame) {
+    if (ctxt == NULL)
+        return;
+    if (ctxt->valueNr < ctxt->valueFrame) {
+        xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR);
+    }
+    ctxt->valueFrame = frame;
+}
+
+/**
  * valuePop:
  * @ctxt: an XPath evaluation context
  *
@@ -2412,6 +2449,12 @@
 
     if ((ctxt == NULL) || (ctxt->valueNr <= 0))
         return (NULL);
+
+    if (ctxt->valueNr <= ctxt->valueFrame) {
+        xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR);
+        return (NULL);
+    }
+
     ctxt->valueNr--;
     if (ctxt->valueNr > 0)
         ctxt->value = ctxt->valueTab[ctxt->valueNr - 1];
@@ -2442,6 +2485,7 @@
                                              sizeof(ctxt->valueTab[0]));
         if (tmp == NULL) {
             xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
+            ctxt->error = XPATH_MEMORY_ERROR;
             return (0);
         }
         ctxt->valueMax *= 2;
@@ -3522,13 +3566,13 @@
     } else if (cur->nodeNr == cur->nodeMax) {
         xmlNodePtr *temp;
 
-        cur->nodeMax *= 2;
-	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
+	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
 				      sizeof(xmlNodePtr));
 	if (temp == NULL) {
 	    xmlXPathErrMemory(NULL, "growing nodeset\n");
 	    return;
 	}
+        cur->nodeMax *= 2;
 	cur->nodeTab = temp;
     }
     cur->nodeTab[cur->nodeNr++] = xmlXPathNodeSetDupNs(node, ns);
@@ -3575,13 +3619,13 @@
     } else if (cur->nodeNr == cur->nodeMax) {
         xmlNodePtr *temp;
 
-        cur->nodeMax *= 2;
-	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
+	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
 				      sizeof(xmlNodePtr));
 	if (temp == NULL) {
 	    xmlXPathErrMemory(NULL, "growing nodeset\n");
 	    return;
 	}
+        cur->nodeMax *= 2;
 	cur->nodeTab = temp;
     }
     if (val->type == XML_NAMESPACE_DECL) {
@@ -3627,14 +3671,14 @@
     } else if (cur->nodeNr == cur->nodeMax) {
         xmlNodePtr *temp;
 
-        cur->nodeMax *= 2;
-	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
+	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
 				      sizeof(xmlNodePtr));
 	if (temp == NULL) {
 	    xmlXPathErrMemory(NULL, "growing nodeset\n");
 	    return;
 	}
 	cur->nodeTab = temp;
+        cur->nodeMax *= 2;
     }
     if (val->type == XML_NAMESPACE_DECL) {
 	xmlNsPtr ns = (xmlNsPtr) val;
@@ -3738,14 +3782,14 @@
 	} else if (val1->nodeNr == val1->nodeMax) {
 	    xmlNodePtr *temp;
 
-	    val1->nodeMax *= 2;
-	    temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *
+	    temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax * 2 *
 					     sizeof(xmlNodePtr));
 	    if (temp == NULL) {
 	        xmlXPathErrMemory(NULL, "merging nodeset\n");
 		return(NULL);
 	    }
 	    val1->nodeTab = temp;
+	    val1->nodeMax *= 2;
 	}
 	if (n2->type == XML_NAMESPACE_DECL) {
 	    xmlNsPtr ns = (xmlNsPtr) n2;
@@ -3907,14 +3951,14 @@
 	    } else if (set1->nodeNr >= set1->nodeMax) {
 		xmlNodePtr *temp;
 
-		set1->nodeMax *= 2;
 		temp = (xmlNodePtr *) xmlRealloc(
-		    set1->nodeTab, set1->nodeMax * sizeof(xmlNodePtr));
+		    set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));
 		if (temp == NULL) {
 		    xmlXPathErrMemory(NULL, "merging nodeset\n");
 		    return(NULL);
 		}
 		set1->nodeTab = temp;
+		set1->nodeMax *= 2;
 	    }
 	    if (n2->type == XML_NAMESPACE_DECL) {
 		xmlNsPtr ns = (xmlNsPtr) n2;
@@ -3991,14 +4035,14 @@
 	    } else if (set1->nodeNr >= set1->nodeMax) {
 		xmlNodePtr *temp;
 
-		set1->nodeMax *= 2;
 		temp = (xmlNodePtr *) xmlRealloc(
-		    set1->nodeTab, set1->nodeMax * sizeof(xmlNodePtr));
+		    set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));
 		if (temp == NULL) {
 		    xmlXPathErrMemory(NULL, "merging nodeset\n");
 		    return(NULL);
 		}
 		set1->nodeTab = temp;
+		set1->nodeMax *= 2;
 	    }
 	    set1->nodeTab[set1->nodeNr++] = n2;
 	}
@@ -5003,7 +5047,7 @@
 /**
  * xmlXPathRegisterNs:
  * @ctxt:  the XPath context
- * @prefix:  the namespace prefix
+ * @prefix:  the namespace prefix cannot be NULL or empty string
  * @ns_uri:  the namespace name
  *
  * Register a new namespace. If @ns_uri is NULL it unregisters
@@ -5018,6 +5062,8 @@
 	return(-1);
     if (prefix == NULL)
 	return(-1);
+    if (prefix[0] == 0)
+	return(-1);
 
     if (ctxt->nsHash == NULL)
 	ctxt->nsHash = xmlHashCreate(10);
@@ -6152,6 +6198,7 @@
     ret->valueNr = 0;
     ret->valueMax = 10;
     ret->value = NULL;
+    ret->valueFrame = 0;
 
     ret->context = ctxt;
     ret->comp = comp;
@@ -8104,9 +8151,17 @@
 xmlNodePtr
 xmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
     if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
-    if (cur != NULL && cur->children != NULL)
-        return cur->children ;
-    if (cur == NULL) cur = ctxt->context->node;
+    if ((cur != NULL) && (cur->type  != XML_ATTRIBUTE_NODE) &&
+        (cur->type != XML_NAMESPACE_DECL) && (cur->children != NULL))
+        return(cur->children);
+
+    if (cur == NULL) {
+        cur = ctxt->context->node;
+        if (cur->type == XML_NAMESPACE_DECL)
+            return(NULL);
+        if (cur->type == XML_ATTRIBUTE_NODE)
+            cur = cur->parent;
+    }
     if (cur == NULL) return(NULL) ; /* ERROR */
     if (cur->next != NULL) return(cur->next) ;
     do {
@@ -8160,8 +8215,13 @@
 xmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur)
 {
     if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
-    if (cur == NULL)
+    if (cur == NULL) {
         cur = ctxt->context->node;
+        if (cur->type == XML_NAMESPACE_DECL)
+            return(NULL);
+        if (cur->type == XML_ATTRIBUTE_NODE)
+            return(cur->parent);
+    }
     if (cur == NULL)
 	return (NULL);
     if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE))
@@ -8205,8 +8265,8 @@
         cur = ctxt->context->node;
         if (cur == NULL)
             return (NULL);
-	if (cur->type == XML_NAMESPACE_DECL)
-	    cur = (xmlNodePtr)((xmlNsPtr)cur)->next;
+        if (cur->type == XML_NAMESPACE_DECL)
+            return (NULL);
         ctxt->ancestor = cur->parent;
     }
     if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE))
@@ -9020,7 +9080,7 @@
      * the index is NaN, the length is NaN, or both
      * arguments are infinity (relying on Inf + -Inf = NaN)
      */
-    if (!xmlXPathIsNaN(in + le) && !xmlXPathIsInf(in)) {
+    if (!xmlXPathIsInf(in) && !xmlXPathIsNaN(in + le)) {
         /*
          * To meet the requirements of the spec, the arguments
 	 * must be converted to integer format before
@@ -9281,6 +9341,7 @@
 		if ( (ch & 0xc0) != 0xc0 ) {
 		    xmlGenericError(xmlGenericErrorContext,
 			"xmlXPathTranslateFunction: Invalid UTF8 string\n");
+                    /* not asserting an XPath error is probably better */
 		    break;
 		}
 		/* then skip over remaining bytes for this char */
@@ -9288,6 +9349,7 @@
 		    if ( (*cptr++ & 0xc0) != 0x80 ) {
 			xmlGenericError(xmlGenericErrorContext,
 			    "xmlXPathTranslateFunction: Invalid UTF8 string\n");
+                        /* not asserting an XPath error is probably better */
 			break;
 		    }
 		if (ch & 0x80) /* must have had error encountered */
@@ -10029,7 +10091,6 @@
 xmlXPathCompNumber(xmlXPathParserContextPtr ctxt)
 {
     double ret = 0.0;
-    double mult = 1;
     int ok = 0;
     int exponent = 0;
     int is_exponent_negative = 0;
@@ -10065,15 +10126,23 @@
     }
 #endif
     if (CUR == '.') {
+	int v, frac = 0;
+	double fraction = 0;
+
         NEXT;
         if (((CUR < '0') || (CUR > '9')) && (!ok)) {
             XP_ERROR(XPATH_NUMBER_ERROR);
         }
-        while ((CUR >= '0') && (CUR <= '9')) {
-            mult /= 10;
-            ret = ret + (CUR - '0') * mult;
+        while ((CUR >= '0') && (CUR <= '9') && (frac < MAX_FRAC)) {
+	    v = (CUR - '0');
+	    fraction = fraction * 10 + v;
+	    frac = frac + 1;
             NEXT;
         }
+        fraction /= my_pow10[frac];
+        ret = ret + fraction;
+        while ((CUR >= '0') && (CUR <= '9'))
+            NEXT;
     }
     if ((CUR == 'e') || (CUR == 'E')) {
         NEXT;
@@ -10866,7 +10935,6 @@
         xmlXPathCompAndExpr(ctxt);
 	CHECK_ERROR;
 	PUSH_BINARY_EXPR(XPATH_OP_OR, op1, ctxt->comp->last, 0, 0);
-	op1 = ctxt->comp->nbStep;
 	SKIP_BLANKS;
     }
     if ((sort) && (ctxt->comp->steps[ctxt->comp->last].op != XPATH_OP_VALUE)) {
@@ -11248,7 +11316,10 @@
 	    }
 	}
 
-	CHECK_ERROR;
+        if (ctxt->error != XPATH_EXPRESSION_OK) {
+            xmlFree(name);
+            return;
+        }
 
 	name = xmlXPathCompNodeTest(ctxt, &test, &type, &prefix, name);
 	if (test == 0)
@@ -11332,6 +11403,7 @@
 	SKIP_BLANKS;
     }
     xmlXPathCompStep(ctxt);
+    CHECK_ERROR;
     SKIP_BLANKS;
     while (CUR == '/') {
 	if ((CUR == '/') && (NXT(1) == '/')) {
@@ -11391,6 +11463,7 @@
 		     (CUR == '@') || (CUR == '*')))
 		    xmlXPathCompRelativeLocationPath(ctxt);
 	    }
+	    CHECK_ERROR;
 	}
     }
 }
@@ -11685,6 +11758,7 @@
 	xmlXPathObjectPtr contextObj = NULL, exprRes = NULL;
 	xmlNodePtr oldContextNode, contextNode = NULL;
 	xmlXPathContextPtr xpctxt = ctxt->context;
+        int frame;
 
 #ifdef LIBXML_XPTR_ENABLED
 	    /*
@@ -11704,6 +11778,8 @@
 	*/
 	exprOp = &ctxt->comp->steps[op->ch2];
 	for (i = 0; i < set->nodeNr; i++) {
+            xmlXPathObjectPtr tmp;
+
 	    if (set->nodeTab[i] == NULL)
 		continue;
 
@@ -11731,23 +11807,25 @@
 		xmlXPathNodeSetAddUnique(contextObj->nodesetval,
 		    contextNode);
 
+            frame = xmlXPathSetFrame(ctxt);
 	    valuePush(ctxt, contextObj);
 	    res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1);
+            tmp = valuePop(ctxt);
+            xmlXPathPopFrame(ctxt, frame);
 
 	    if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) {
-	        xmlXPathObjectPtr tmp;
-	        /* pop the result if any */
-	        tmp = valuePop(ctxt);
-	        while (tmp != contextObj) {
-	            /*
-	             * Free up the result
-	             * then pop off contextObj, which will be freed later
-	             */
-	             xmlXPathReleaseObject(xpctxt, tmp);
-	             tmp = valuePop(ctxt);
-	        }
+                while (tmp != contextObj) {
+                    /*
+                     * Free up the result
+                     * then pop off contextObj, which will be freed later
+                     */
+                    xmlXPathReleaseObject(xpctxt, tmp);
+                    tmp = valuePop(ctxt);
+                }
 		goto evaluation_error;
 	    }
+            /* push the result back onto the stack */
+            valuePush(ctxt, tmp);
 
 	    if (res)
 		pos++;
@@ -11984,7 +12062,6 @@
     *   avoid a duplicate-aware merge, if the axis to be traversed is e.g.
     *   the descendant-or-self axis.
     */
-    addNode = xmlXPathNodeSetAdd;
     mergeAndClear = xmlXPathNodeSetMergeAndClear;
     switch (axis) {
         case AXIS_ANCESTOR:
@@ -12658,7 +12735,7 @@
             return (total);
 #ifdef XP_OPTIMIZED_FILTER_FIRST
 	case XPATH_OP_FILTER:
-                total =+ xmlXPathCompOpEvalFilterFirst(ctxt, op, first);
+                total += xmlXPathCompOpEvalFilterFirst(ctxt, op, first);
             return (total);
 #endif
         default:
@@ -13336,6 +13413,7 @@
                         xmlGenericError(xmlGenericErrorContext,
             "xmlXPathCompOpEval: variable %s bound to undefined prefix %s\n",
                                     (char *) op->value4, (char *)op->value5);
+                        ctxt->error = XPATH_UNDEF_PREFIX_ERROR;
                         return (total);
                     }
 		    val = xmlXPathVariableLookupNS(ctxt->context,
@@ -13352,7 +13430,9 @@
                 xmlXPathFunction func;
                 const xmlChar *oldFunc, *oldFuncURI;
 		int i;
+                int frame;
 
+                frame = xmlXPathSetFrame(ctxt);
                 if (op->ch1 != -1)
                     total +=
                         xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
@@ -13360,15 +13440,18 @@
 		    xmlGenericError(xmlGenericErrorContext,
 			    "xmlXPathCompOpEval: parameter error\n");
 		    ctxt->error = XPATH_INVALID_OPERAND;
+                    xmlXPathPopFrame(ctxt, frame);
 		    return (total);
 		}
-		for (i = 0; i < op->value; i++)
+		for (i = 0; i < op->value; i++) {
 		    if (ctxt->valueTab[(ctxt->valueNr - 1) - i] == NULL) {
 			xmlGenericError(xmlGenericErrorContext,
 				"xmlXPathCompOpEval: parameter error\n");
 			ctxt->error = XPATH_INVALID_OPERAND;
+                        xmlXPathPopFrame(ctxt, frame);
 			return (total);
 		    }
+                }
                 if (op->cache != NULL)
                     XML_CAST_FPTR(func) = op->cache;
                 else {
@@ -13384,6 +13467,8 @@
                             xmlGenericError(xmlGenericErrorContext,
             "xmlXPathCompOpEval: function %s bound to undefined prefix %s\n",
                                     (char *)op->value4, (char *)op->value5);
+                            xmlXPathPopFrame(ctxt, frame);
+                            ctxt->error = XPATH_UNDEF_PREFIX_ERROR;
                             return (total);
                         }
                         func = xmlXPathFunctionLookupNS(ctxt->context,
@@ -13405,6 +13490,7 @@
                 func(ctxt, op->value);
                 ctxt->context->function = oldFunc;
                 ctxt->context->functionURI = oldFuncURI;
+                xmlXPathPopFrame(ctxt, frame);
                 return (total);
             }
         case XPATH_OP_ARG:
@@ -13961,6 +14047,7 @@
     }
     xmlGenericError(xmlGenericErrorContext,
                     "XPath: unknown precompiled operation %d\n", op->op);
+    ctxt->error = XPATH_INVALID_OPERAND;
     return (total);
 }
 
@@ -14308,6 +14395,7 @@
 	ctxt->valueNr = 0;
 	ctxt->valueMax = 10;
 	ctxt->value = NULL;
+        ctxt->valueFrame = 0;
     }
 #ifdef XPATH_STREAMING
     if (ctxt->comp->stream) {
@@ -14508,7 +14596,7 @@
 		    namespaces[i++] = ns->prefix;
 		}
 		namespaces[i++] = NULL;
-		namespaces[i++] = NULL;
+		namespaces[i] = NULL;
 	    }
 	}
 
diff --git a/xpointer.c b/xpointer.c
index 5298fa5..37afa3a 100644
--- a/xpointer.c
+++ b/xpointer.c
@@ -1152,10 +1152,12 @@
     if (name == NULL)
 	XP_ERROR(XPATH_EXPR_ERROR);
     while (name != NULL) {
+	ctxt->error = XPATH_EXPRESSION_OK;
 	xmlXPtrEvalXPtrPart(ctxt, name);
 
 	/* in case of syntax error, break here */
-	if (ctxt->error != XPATH_EXPRESSION_OK)
+	if ((ctxt->error != XPATH_EXPRESSION_OK) &&
+            (ctxt->error != XML_XPTR_UNKNOWN_SCHEME))
 	    return;
 
 	/*
@@ -1267,6 +1269,7 @@
 	ctxt->valueNr = 0;
 	ctxt->valueMax = 10;
 	ctxt->value = NULL;
+	ctxt->valueFrame = 0;
     }
     SKIP_BLANKS;
     if (CUR == '/') {
@@ -1299,12 +1302,19 @@
  *									*
  ************************************************************************/
 
+static
 void xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs);
+static
 void xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs);
+static
 void xmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs);
+static
 void xmlXPtrHereFunction(xmlXPathParserContextPtr ctxt, int nargs);
+static
 void xmlXPtrOriginFunction(xmlXPathParserContextPtr ctxt, int nargs);
+static
 void xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs);
+static
 void xmlXPtrRangeFunction(xmlXPathParserContextPtr ctxt, int nargs);
 
 /**
@@ -1732,7 +1742,7 @@
  * Function implementing here() operation 
  * as described in 5.4.3
  */
-void
+static void
 xmlXPtrHereFunction(xmlXPathParserContextPtr ctxt, int nargs) {
     CHECK_ARITY(0);
 
@@ -1750,7 +1760,7 @@
  * Function implementing origin() operation 
  * as described in 5.4.3
  */
-void
+static void
 xmlXPtrOriginFunction(xmlXPathParserContextPtr ctxt, int nargs) {
     CHECK_ARITY(0);
 
@@ -1783,7 +1793,7 @@
  * ----------------
  *
  */
-void
+static void
 xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
     xmlXPathObjectPtr tmp, obj, point;
     xmlLocationSetPtr newset = NULL;
@@ -1877,7 +1887,7 @@
  *   syntax error.
  * ----------------------------
  */
-void
+static void
 xmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
     xmlXPathObjectPtr tmp, obj, point;
     xmlLocationSetPtr newset = NULL;
@@ -2022,7 +2032,7 @@
  *  location-set, a range location representing the covering range of
  *  x is added to the result location-set.
  */
-void
+static void
 xmlXPtrRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
     int i;
     xmlXPathObjectPtr set;
@@ -2168,7 +2178,7 @@
  *  location children of x.
  *
  */
-void
+static void
 xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs) {
     int i;
     xmlXPathObjectPtr set;
@@ -2622,13 +2632,12 @@
 
     if (cur == NULL)
 	return(-1);
-    
+
     if ((cur->type == XML_ELEMENT_NODE) ||
 	(cur->type == XML_DOCUMENT_NODE) ||
 	(cur->type == XML_HTML_DOCUMENT_NODE)) {
 	if (pos > 0) {
 	    cur = xmlXPtrGetNthChild(cur, pos);
-	    pos = 0;
 	}
     }
     while (cur != NULL) {
@@ -2757,7 +2766,7 @@
  * all be character points.
  * ------------------------------
  */
-void
+static void
 xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
     int i, startindex, endindex = 0, fendindex;
     xmlNodePtr start, end = 0, fend;