Finally had a bit of time to resynch both trees:
- HTMLparser.[ch]: added a way to avoid adding automatically
  omitted tags. htmlHandleOmittedElem() allows to change the
  default handling.
- tree.[ch] xmllint.c: added xmlDocDumpFormatMemory() and
  xmlDocDumpFormatMemoryEnc(), uses memory functions for output
  of xmllint too when using --memory flag, added a memory test
  suite at the Makefile level.
- xpathInternals.h xpath.[ch] xpointer.c: fixed problems
  with namespace use when encountering QNames in XPath evalation,
  added xmlns() scheme in XPointer.
- nanoftp.c : incorporated a fix
- parser.c xmlIO.c: fixed problems raised with encoding when using
  the memory I/O
- parserInternals.c: closed bug 25934 reported by
  torsten.landschoff@innominate.de
- TODO: updated
Daniel
diff --git a/ChangeLog b/ChangeLog
index f86f81a..d1d2490 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+Wed Dec 27 12:35:49 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* HTMLparser.[ch]: added a way to avoid adding automatically
+	  omitted tags. htmlHandleOmittedElem() allows to change the
+	  default handling.
+	* tree.[ch] xmllint.c: added xmlDocDumpFormatMemory() and 
+	  xmlDocDumpFormatMemoryEnc(), uses memory functions for output
+	  of xmllint too when using --memory flag, added a memory test
+	  suite at the Makefile level.
+	* xpathInternals.h xpath.[ch] xpointer.c: fixed problems
+	  with namespace use when encountering QNames in XPath evalation,
+	  added xmlns() scheme in XPointer.
+	* nanoftp.c : incorporated a fix
+	* parser.c xmlIO.c: fixed problems raised with encoding when using
+	  the memory I/O
+	* parserInternals.c: closed bug 25934 reported by 
+	  torsten.landschoff@innominate.de
+	* TODO: updated
+
 Sat Nov 25 11:46:27 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
 
 	* configure.in doc/html/* doc/xml.html: made a 2.2.9 release
diff --git a/HTMLparser.c b/HTMLparser.c
index f2831f6..a494132 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -53,6 +53,8 @@
 /* #define DEBUG */
 /* #define DEBUG_PUSH */
 
+int htmlOmittedDefaultValue = 1;
+
 /************************************************************************
  *									*
  * 		Parser stacks related functions and macros		*
@@ -837,12 +839,14 @@
  * @ctxt:  an HTML parser context
  * @newtag:  The new tag name
  *
- * The HTmL DtD allows a tag to exists only implicitely
+ * The HTML DtD allows a tag to exists only implicitely
  * called when a new tag has been detected and generates the
  * appropriates implicit tags if missing
  */
 void
 htmlCheckImplied(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
+    if (!htmlOmittedDefaultValue)
+	return;
     if (xmlStrEqual(newtag, BAD_CAST"html"))
 	return;
     if (ctxt->nameNr <= 0) {
@@ -2787,6 +2791,10 @@
     if ((ctxt == NULL) || (attvalue == NULL))
 	return;
 
+    /* do not change encoding */	
+    if (ctxt->input->encoding != NULL)
+        return;
+
     encoding = xmlStrcasestr(attvalue, BAD_CAST"charset=");
     if (encoding != NULL) {
 	encoding += 8;
@@ -4822,6 +4830,7 @@
     htmlParserInputPtr inputStream;
     xmlParserInputBufferPtr buf;
     /* htmlCharEncoding enc; */
+    xmlChar *content, *content_line = (xmlChar *) "charset=";
 
     buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
     if (buf == NULL) return(NULL);
@@ -4852,6 +4861,18 @@
     inputStream->free = NULL;
 
     inputPush(ctxt, inputStream);
+    
+    /* set encoding */
+    if (encoding) {
+        content = xmlMalloc (xmlStrlen(content_line) + strlen(encoding) + 1);
+	if (content) {  
+	    strcpy ((char *)content, (char *)content_line);
+            strcat ((char *)content, (char *)encoding);
+            htmlCheckEncoding (ctxt, content);
+	    xmlFree (content);
+	}
+    }
+    
     return(ctxt);
 }
 
@@ -4913,4 +4934,21 @@
     return(htmlSAXParseFile(filename, encoding, NULL, NULL));
 }
 
+/**
+ * htmlHandleOmittedElem:
+ * @val:  int 0 or 1 
+ *
+ * Set and return the previous value for handling HTML omitted tags.
+ *
+ * Returns the last value for 0 for no handling, 1 for auto insertion.
+ */
+
+int
+htmlHandleOmittedElem(int val) {
+    int old = htmlOmittedDefaultValue;
+
+    htmlOmittedDefaultValue = val;
+    return(old);
+}
+
 #endif /* LIBXML_HTML_ENABLED */
diff --git a/HTMLparser.h b/HTMLparser.h
index be95357..b70c0a1 100644
--- a/HTMLparser.h
+++ b/HTMLparser.h
@@ -91,6 +91,7 @@
 					 const unsigned char* in,
 					 int *inlen, int quoteChar);
 int			htmlIsScriptAttribute(const xmlChar *name);
+int			htmlHandleOmittedElem(int val);
 
 /**
  * Interfaces for the Push mode
diff --git a/Makefile.am b/Makefile.am
index 1e711fe..1bd18c3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -179,6 +179,24 @@
 	      diff result.$$name result2.$$name ; \
 	      rm result.$$name result2.$$name ; \
 	  fi ; fi ; done)
+	@echo "##"
+	@echo "## XML regression tests on memory"
+	@echo "##"
+	@(for i in $(srcdir)/test/* ; do \
+	  name=`basename $$i`; \
+	  if [ ! -d $$i ] ; then \
+	  if [ ! -f $(srcdir)/result/$$name ] ; then \
+	      echo New test file $$name ; \
+	      $(top_builddir)/xmllint --memory $$i > $(srcdir)/result/$$name ; \
+	  else \
+	      echo Testing $$name ; \
+	      $(top_builddir)/xmllint --memory $$i > result.$$name ; \
+	      grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0";\
+	      diff $(srcdir)/result/$$name result.$$name ; \
+	      $(top_builddir)/xmllint --memory result.$$name > result2.$$name ; \
+	      diff result.$$name result2.$$name ; \
+	      rm result.$$name result2.$$name ; \
+	  fi ; fi ; done)
 
 XMLenttests : xmllint
 	@echo "##"
diff --git a/TODO b/TODO
index 61ba935..e83773a 100644
--- a/TODO
+++ b/TODO
@@ -32,6 +32,9 @@
 - jamesh suggestion: SAX like functions to save a document ie. call a
   function to open a new element with given attributes, write character
   data, close last element, etc
+- htmlParseDoc has parameter encoding which is not used.
+  Function htmlCreateDocParserCtxt ignore it.
+
 
 TODO:
 =====
diff --git a/aclocal.m4 b/aclocal.m4
index 869e5fc..e372675 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -620,31 +620,35 @@
 ])
 
 # AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
-# the libltdl convenience library, adds --enable-ltdl-convenience to
-# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
-# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
-# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
-# '${top_builddir}/' (note the single quotes!) if your package is not
-# flat, and, if you're not using automake, define top_builddir as
-# appropriate in the Makefiles.
+# the libltdl convenience library and INCLTDL to the include flags for
+# the libltdl header and adds --enable-ltdl-convenience to the
+# configure arguments.  Note that LIBLTDL and INCLTDL are not
+# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called.  If DIR is not
+# provided, it is assumed to be `libltdl'.  LIBLTDL will be prefixed
+# with '${top_builddir}/' and INCLTDL will be prefixed with
+# '${top_srcdir}/' (note the single quotes!).  If your package is not
+# flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
 AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
   case "$enable_ltdl_convenience" in
   no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
   "") enable_ltdl_convenience=yes
       ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
   esac
-  LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
-  INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+  LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
+  INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
 ])
 
 # AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
-# the libltdl installable library, and adds --enable-ltdl-install to
-# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
-# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
-# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
-# '${top_builddir}/' (note the single quotes!) if your package is not
-# flat, and, if you're not using automake, define top_builddir as
-# appropriate in the Makefiles.
+# the libltdl installable library and INCLTDL to the include flags for
+# the libltdl header and adds --enable-ltdl-install to the configure
+# arguments.  Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is
+# AC_CONFIG_SUBDIRS called.  If DIR is not provided and an installed
+# libltdl is not found, it is assumed to be `libltdl'.  LIBLTDL will
+# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed
+# with '${top_srcdir}/' (note the single quotes!).  If your package is
+# not flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
 # In the future, this macro may have to be called after AC_PROG_LIBTOOL.
 AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
   AC_CHECK_LIB(ltdl, main,
@@ -657,8 +661,8 @@
   ])
   if test x"$enable_ltdl_install" = x"yes"; then
     ac_configure_args="$ac_configure_args --enable-ltdl-install"
-    LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
-    INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+    LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
+    INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
   else
     ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
     LIBLTDL="-lltdl"
diff --git a/include/libxml/HTMLparser.h b/include/libxml/HTMLparser.h
index be95357..b70c0a1 100644
--- a/include/libxml/HTMLparser.h
+++ b/include/libxml/HTMLparser.h
@@ -91,6 +91,7 @@
 					 const unsigned char* in,
 					 int *inlen, int quoteChar);
 int			htmlIsScriptAttribute(const xmlChar *name);
+int			htmlHandleOmittedElem(int val);
 
 /**
  * Interfaces for the Push mode
diff --git a/include/libxml/tree.h b/include/libxml/tree.h
index 7b19d09..2dc3242 100644
--- a/include/libxml/tree.h
+++ b/include/libxml/tree.h
@@ -634,6 +634,10 @@
 /*
  * Saving
  */
+void		xmlDocDumpFormatMemory	(xmlDocPtr cur,
+					 xmlChar**mem,
+					 int *size,
+					 int format);
 void		xmlDocDumpMemory	(xmlDocPtr cur,
 					 xmlChar**mem,
 					 int *size);
@@ -641,6 +645,11 @@
 					 xmlChar **doc_txt_ptr,
 					 int * doc_txt_len,
 					 const char *txt_encoding);
+void		xmlDocDumpFormatMemoryEnc(xmlDocPtr out_doc,
+					 xmlChar **doc_txt_ptr,
+					 int * doc_txt_len,
+					 const char *txt_encoding,
+					 int format);
 int		xmlDocDump		(FILE *f,
 					 xmlDocPtr cur);
 void		xmlElemDump		(FILE *f,
diff --git a/include/libxml/xpath.h b/include/libxml/xpath.h
index 553b3fc..6f820d4 100644
--- a/include/libxml/xpath.h
+++ b/include/libxml/xpath.h
@@ -47,7 +47,8 @@
     XPATH_MEMORY_ERROR,
     XPTR_SYNTAX_ERROR,
     XPTR_RESOURCE_ERROR,
-    XPTR_SUB_RESOURCE_ERROR
+    XPTR_SUB_RESOURCE_ERROR,
+    XPATH_UNDEF_PREFIX_ERROR
 } xmlXPathError;
 
 /*
@@ -171,6 +172,8 @@
  *    - a set of variable bindings 
  *    - a function library 
  *    - the set of namespace declarations in scope for the expression 
+ * Following the switch to hash tables, this need to be trimmed up at
+ * the next binary incompatible release.
  */
 
 struct _xmlXPathContext {
@@ -193,10 +196,10 @@
     int max_axis;			/* max number of axis */
     xmlXPathAxisPtr axis;		/* Array of defined axis */
 
-    /* Namespace traversal should be implemented with user */
-    xmlNsPtr *namespaces;		/* The namespaces lookup */
-    int nsNr;				/* the current Namespace index */
-    void *user;				/* user defined extra info */
+    /* the namespace nodes of the context node */
+    xmlNsPtr *namespaces;		/* Array of namespaces */
+    int nsNr;				/* number of namespace in scope */
+    void *user;				/* function to free */
 
     /* extra variables */
     int contextSize;			/* the context size */
@@ -206,6 +209,9 @@
     int xptr;				/* it this an XPointer context */
     xmlNodePtr here;			/* for here() */
     xmlNodePtr origin;			/* for origin() */
+
+    /* the set of namespace declarations in scope for the expression */
+    xmlHashTablePtr nsHash;		/* The namespaces hash table */
 };
 
 /*
diff --git a/include/libxml/xpathInternals.h b/include/libxml/xpathInternals.h
index a18e453..6967c90 100644
--- a/include/libxml/xpathInternals.h
+++ b/include/libxml/xpathInternals.h
@@ -68,6 +68,13 @@
 /**
  * Extending a context
  */
+int		   xmlXPathRegisterNs		(xmlXPathContextPtr ctxt,
+						 const xmlChar *prefix,
+						 const xmlChar *ns_uri);
+const xmlChar *	   xmlXPathNsLookup		(xmlXPathContextPtr ctxt,
+						 const xmlChar *ns_uri);
+void		   xmlXPathRegisteredNsCleanup	(xmlXPathContextPtr ctxt);
+
 int		   xmlXPathRegisterFunc		(xmlXPathContextPtr ctxt,
 						 const xmlChar *name,
 						 xmlXPathFunction f);
@@ -121,6 +128,7 @@
 void		  xmlXPathRoot			(xmlXPathParserContextPtr ctxt);
 void		  xmlXPathEvalExpr		(xmlXPathParserContextPtr ctxt);
 xmlChar *	  xmlXPathParseName		(xmlXPathParserContextPtr ctxt);
+xmlChar *	  xmlXPathParseNCName		(xmlXPathParserContextPtr ctxt);
 
 /*
  * Debug
diff --git a/nanoftp.c b/nanoftp.c
index 1207355..c7ea79a 100644
--- a/nanoftp.c
+++ b/nanoftp.c
@@ -650,6 +650,9 @@
      * and analyzed.
      */
     len = xmlNanoFTPGetMore(ctx);
+    if (len < 0) {
+        return(-1);
+    }
     if ((ctxt->controlBufUsed == 0) && (len == 0)) {
         return(-1);
     }
diff --git a/parser.c b/parser.c
index c3ea2a3..f3f0565 100644
--- a/parser.c
+++ b/parser.c
@@ -8189,17 +8189,23 @@
 
 	if ((terminate) || (ctxt->input->buf->buffer->use > 80))
 	    xmlParseTryOrFinish(ctxt, terminate);
-    } else if (ctxt->instate != XML_PARSER_EOF)
-      if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
-      xmlParserInputBufferPtr in = ctxt->input->buf;
-      int nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
-      if (nbchars < 0) {
-          xmlGenericError(xmlGenericErrorContext,
-                  "xmlParseChunk: encoder error\n");
-          return(XML_ERR_INVALID_ENCODING);
-      }
-      }
-        xmlParseTryOrFinish(ctxt, terminate);
+    } else if (ctxt->instate != XML_PARSER_EOF) {
+	if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
+	    xmlParserInputBufferPtr in = ctxt->input->buf;
+	    if ((in->encoder != NULL) && (in->buffer != NULL) &&
+		    (in->raw != NULL)) {
+		int nbchars;
+		    
+		nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
+		if (nbchars < 0) {
+		    xmlGenericError(xmlGenericErrorContext,
+				    "xmlParseChunk: encoder error\n");
+		    return(XML_ERR_INVALID_ENCODING);
+		}
+	    }
+	}
+    }
+    xmlParseTryOrFinish(ctxt, terminate);
     if (terminate) {
 	/*
 	 * Check for termination
@@ -9234,6 +9240,7 @@
     } else {
 	inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
 	if (inputStream == NULL) {
+	    xmlFree(uri);
 	    xmlFreeParserCtxt(ctxt);
 	    return(NULL);
 	}
diff --git a/parserInternals.c b/parserInternals.c
index d9cde91..a20faf5 100644
--- a/parserInternals.c
+++ b/parserInternals.c
@@ -481,7 +481,7 @@
       (((c) >= 0x06D0) && ((c) <= 0x06D3)) ||
       ((c) == 0x06D5) ||
       (((c) >= 0x06E5) && ((c) <= 0x06E6)) ||
-     (((c) > 0x905) && (	/* accelerator */
+     (((c) >= 0x905) && (	/* accelerator */
       (((c) >= 0x0905) && ((c) <= 0x0939)) ||
       ((c) == 0x093D) ||
       (((c) >= 0x0958) && ((c) <= 0x0961)) ||
@@ -572,7 +572,7 @@
       (((c) >= 0x0EC0) && ((c) <= 0x0EC4)) ||
       (((c) >= 0x0F40) && ((c) <= 0x0F47)) ||
       (((c) >= 0x0F49) && ((c) <= 0x0F69)) ||
-     (((c) > 0x10A0) && (	/* accelerator */
+     (((c) >= 0x10A0) && (	/* accelerator */
       (((c) >= 0x10A0) && ((c) <= 0x10C5)) ||
       (((c) >= 0x10D0) && ((c) <= 0x10F6)) ||
       ((c) == 0x1100) ||
@@ -697,7 +697,7 @@
       (((c) >= 0x06E0) && ((c) <= 0x06E4)) ||
       (((c) >= 0x06E7) && ((c) <= 0x06E8)) ||
       (((c) >= 0x06EA) && ((c) <= 0x06ED)) ||
-     (((c) > 0x0901) && (	/* accelerator */
+     (((c) >= 0x0901) && (	/* accelerator */
       (((c) >= 0x0901) && ((c) <= 0x0903)) ||
       ((c) == 0x093C) ||
       (((c) >= 0x093E) && ((c) <= 0x094C)) ||
@@ -713,7 +713,7 @@
       (((c) >= 0x09CB) && ((c) <= 0x09CD)) ||
       ((c) == 0x09D7) ||
       (((c) >= 0x09E2) && ((c) <= 0x09E3)) ||
-     (((c) > 0x0A02) && (	/* accelerator */
+     (((c) >= 0x0A02) && (	/* accelerator */
       ((c) == 0x0A02) ||
       ((c) == 0x0A3C) ||
       ((c) == 0x0A3E) ||
@@ -753,7 +753,7 @@
       (((c) >= 0x0D46) && ((c) <= 0x0D48)) ||
       (((c) >= 0x0D4A) && ((c) <= 0x0D4D)) ||
       ((c) == 0x0D57) ||
-     (((c) > 0x0E31) && (	/* accelerator */
+     (((c) >= 0x0E31) && (	/* accelerator */
       ((c) == 0x0E31) ||
       (((c) >= 0x0E34) && ((c) <= 0x0E3A)) ||
       (((c) >= 0x0E47) && ((c) <= 0x0E4E)) ||
diff --git a/tree.c b/tree.c
index 1d6c3a1..8d24503 100644
--- a/tree.c
+++ b/tree.c
@@ -5098,44 +5098,6 @@
     xmlBufferFree(buf);
 }
 
-/**
- * xmlDocContentDump:
- * @buf:  the XML buffer output
- * @cur:  the document
- *
- * Dump an XML document.
- */
-static void
-xmlDocContentDump(xmlBufferPtr buf, xmlDocPtr cur) {
-    xmlBufferWriteChar(buf, "<?xml version=");
-    if (cur->version != NULL) 
-	xmlBufferWriteQuotedString(buf, cur->version);
-    else
-	xmlBufferWriteChar(buf, "\"1.0\"");
-    if (cur->encoding != NULL) {
-        xmlBufferWriteChar(buf, " encoding=");
-	xmlBufferWriteQuotedString(buf, cur->encoding);
-    }
-    switch (cur->standalone) {
-        case 0:
-	    xmlBufferWriteChar(buf, " standalone=\"no\"");
-	    break;
-        case 1:
-	    xmlBufferWriteChar(buf, " standalone=\"yes\"");
-	    break;
-    }
-    xmlBufferWriteChar(buf, "?>\n");
-    if (cur->children != NULL) {
-        xmlNodePtr child = cur->children;
-
-	while (child != NULL) {
-	    xmlNodeDump(buf, cur, child, 0, 0);
-	    xmlBufferWriteChar(buf, "\n");
-	    child = child->next;
-	}
-    }
-}
-
 /************************************************************************
  *									*
  *   		Dumping XML tree content to an I/O output buffer	*
@@ -5522,12 +5484,13 @@
  * @buf:  the XML buffer output
  * @cur:  the document
  * @encoding:  an optional encoding string
+ * @format:  should formatting spaces been added
  *
  * Dump an XML document.
  */
 static void
 xmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
-	                const char *encoding) {
+	                const char *encoding, int format) {
     xmlOutputBufferWriteString(buf, "<?xml version=");
     if (cur->version != NULL) 
 	xmlBufferWriteQuotedString(buf->buffer, cur->version);
@@ -5556,7 +5519,7 @@
         xmlNodePtr child = cur->children;
 
 	while (child != NULL) {
-	    xmlNodeDumpOutput(buf, cur, child, 0, 1, encoding);
+	    xmlNodeDumpOutput(buf, cur, child, 0, format, encoding);
 	    xmlOutputBufferWriteString(buf, "\n");
 	    child = child->next;
 	}
@@ -5570,6 +5533,105 @@
  ************************************************************************/
 
 /**
+ * xmlDocDumpMemoryEnc:
+ * @out_doc:  Document to generate XML text from
+ * @doc_txt_ptr:  Memory pointer for allocated XML text
+ * @doc_txt_len:  Length of the generated XML text
+ * @txt_encoding:  Character encoding to use when generating XML text
+ * @format:  should formatting spaces been added
+ *
+ * Dump the current DOM tree into memory using the character encoding specified
+ * by the caller.  Note it is up to the caller of this function to free the
+ * allocated memory.
+ */
+
+void
+xmlDocDumpFormatMemoryEnc(xmlDocPtr out_doc, xmlChar **doc_txt_ptr,
+		int * doc_txt_len, const char * txt_encoding, int format) {
+    int                         dummy = 0;
+
+    xmlCharEncoding             doc_charset;
+    xmlOutputBufferPtr          out_buff = NULL;
+    xmlCharEncodingHandlerPtr   conv_hdlr = NULL;
+
+    if (doc_txt_len == NULL) {
+        doc_txt_len = &dummy;   /*  Continue, caller just won't get length */
+    }
+
+    if (doc_txt_ptr == NULL) {
+        *doc_txt_len = 0;
+        xmlGenericError(xmlGenericErrorContext,
+                    "xmlDocDumpFormatMemoryEnc:  Null return buffer pointer.");
+        return;
+    }
+
+    *doc_txt_ptr = NULL;
+    *doc_txt_len = 0;
+
+    if (out_doc == NULL) {
+        /*  No document, no output  */
+        xmlGenericError(xmlGenericErrorContext,
+                "xmlDocDumpFormatMemoryEnc:  Null DOM tree document pointer.\n");
+        return;
+    }
+
+    /*
+     *  Validate the encoding value, if provided.
+     *  This logic is copied from xmlSaveFileEnc.
+     */
+
+    if (txt_encoding == NULL)
+	txt_encoding = (const char *) out_doc->encoding;
+    if (txt_encoding != NULL) {
+        doc_charset = xmlParseCharEncoding(txt_encoding);
+
+        if (out_doc->charset != XML_CHAR_ENCODING_UTF8) {
+            xmlGenericError(xmlGenericErrorContext,
+                    "xmlDocDumpFormatMemoryEnc: Source document not in UTF8\n");
+            return;
+
+        } else if (doc_charset != XML_CHAR_ENCODING_UTF8) {
+            conv_hdlr = xmlFindCharEncodingHandler(txt_encoding);
+            if ( conv_hdlr == NULL ) {
+                xmlGenericError(xmlGenericErrorContext,
+                                "%s:  %s %s '%s'\n",
+                                "xmlDocDumpFormatMemoryEnc",
+                                "Failed to identify encoding handler for",
+                                "character set",
+                                txt_encoding);
+                return;
+            }
+        }
+    }
+
+    if ((out_buff = xmlAllocOutputBuffer(conv_hdlr)) == NULL ) {
+        xmlGenericError(xmlGenericErrorContext,
+	    "xmlDocDumpFormatMemoryEnc: Failed to allocate output buffer.\n");
+        return;
+    }
+
+    xmlDocContentDumpOutput(out_buff, out_doc, txt_encoding, 1);
+    xmlOutputBufferFlush(out_buff);
+    if (out_buff->conv != NULL) {
+	*doc_txt_len = out_buff->conv->use;
+	*doc_txt_ptr = xmlStrndup(out_buff->conv->content, *doc_txt_len);
+    } else {
+	*doc_txt_len = out_buff->buffer->use;
+	*doc_txt_ptr = xmlStrndup(out_buff->buffer->content, *doc_txt_len);
+    }
+    (void)xmlOutputBufferClose(out_buff);
+
+    if ((*doc_txt_ptr == NULL) && (*doc_txt_len > 0)) {
+        *doc_txt_len = 0;
+        xmlGenericError(xmlGenericErrorContext,
+                "xmlDocDumpFormatMemoryEnc:  %s\n",
+                "Failed to allocate memory for document text representation.");
+    }
+
+    return;
+}
+
+/**
  * xmlDocDumpMemory:
  * @cur:  the document
  * @mem:  OUT: the memory pointer
@@ -5580,27 +5642,23 @@
  */
 void
 xmlDocDumpMemory(xmlDocPtr cur, xmlChar**mem, int *size) {
-    xmlBufferPtr buf;
+    xmlDocDumpFormatMemoryEnc(cur, mem, size, NULL, 0);
+}
 
-    if (cur == NULL) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlDocDumpMemory : document == NULL\n");
-#endif
-	*mem = NULL;
-	*size = 0;
-	return;
-    }
-    buf = xmlBufferCreate();
-    if (buf == NULL) {
-	*mem = NULL;
-	*size = 0;
-	return;
-    }
-    xmlDocContentDump(buf, cur);
-    *mem = xmlStrndup(buf->content, buf->use);
-    *size = buf->use;
-    xmlBufferFree(buf);
+/**
+ * xmlDocDumpFormatMemory:
+ * @cur:  the document
+ * @mem:  OUT: the memory pointer
+ * @size:  OUT: the memory lenght
+ * @format:  should formatting spaces been added
+ *
+ *
+ * Dump an XML document in memory and return the xmlChar * and it's size.
+ * It's up to the caller to free the memory.
+ */
+void
+xmlDocDumpFormatMemory(xmlDocPtr cur, xmlChar**mem, int *size, int format) {
+    xmlDocDumpFormatMemoryEnc(cur, mem, size, NULL, format);
 }
 
 /**
@@ -5618,79 +5676,8 @@
 void
 xmlDocDumpMemoryEnc(xmlDocPtr out_doc, xmlChar **doc_txt_ptr,
 	            int * doc_txt_len, const char * txt_encoding) {
-    int                         dummy = 0;
-
-    xmlCharEncoding             doc_charset;
-    xmlOutputBufferPtr          out_buff = NULL;
-    xmlCharEncodingHandlerPtr   conv_hdlr = NULL;
-
-    if (doc_txt_len == NULL) {
-        doc_txt_len = &dummy;   /*  Continue, caller just won't get length */
-    }
-
-    if (doc_txt_ptr == NULL) {
-        *doc_txt_len = 0;
-        xmlGenericError(xmlGenericErrorContext,
-                    "xmlDocDumpMemoryEnc:  Null return buffer pointer.");
-        return;
-    }
-
-    *doc_txt_ptr = NULL;
-    *doc_txt_len = 0;
-
-    if (out_doc == NULL) {
-        /*  No document, no output  */
-        xmlGenericError(xmlGenericErrorContext,
-                "xmlDocDumpMemoryEnc:  Null DOM tree document pointer.\n");
-        return;
-    }
-
-    /*
-     *  Validate the encoding value, if provided.
-     *  This logic is copied from xmlSaveFileEnc.
-     */
-
-    if (txt_encoding != NULL) {
-        doc_charset = xmlParseCharEncoding(txt_encoding);
-
-        if (out_doc->charset != XML_CHAR_ENCODING_UTF8) {
-            xmlGenericError(xmlGenericErrorContext,
-                    "xmlDocDumpMemoryEnc:  Source document not in UTF8\n");
-            return;
-
-        } else if (doc_charset != XML_CHAR_ENCODING_UTF8) {
-            conv_hdlr = xmlFindCharEncodingHandler(txt_encoding);
-            if ( conv_hdlr == NULL ) {
-                xmlGenericError(xmlGenericErrorContext,
-                                "%s:  %s %s '%s'\n",
-                                "xmlDocDumpMemoryEnc",
-                                "Failed to identify encoding handler for",
-                                "character set",
-                                txt_encoding);
-                return;
-            }
-        }
-    }
-
-    if ((out_buff = xmlAllocOutputBuffer(conv_hdlr)) == NULL ) {
-        xmlGenericError(xmlGenericErrorContext,
-                "xmlDocDumpMemoryEnc:  Failed to allocate output buffer.\n");
-        return;
-    }
-
-    xmlDocContentDumpOutput(out_buff, out_doc, txt_encoding);
-    *doc_txt_len = out_buff->buffer->use;
-    *doc_txt_ptr = xmlStrndup(out_buff->buffer->content, *doc_txt_len);
-    (void)xmlOutputBufferClose(out_buff);
-
-    if ((*doc_txt_ptr == NULL) && (*doc_txt_len > 0)) {
-        *doc_txt_len = 0;
-        xmlGenericError(xmlGenericErrorContext,
-                "xmlDocDumpMemoryEnc:  %s\n",
-                "Failed to allocate memory for document text representation.");
-    }
-
-    return;
+    xmlDocDumpFormatMemoryEnc(out_doc, doc_txt_ptr, doc_txt_len,
+	                      txt_encoding, 1);
 }
 
 /**
@@ -5792,7 +5779,7 @@
     }
     buf = xmlOutputBufferCreateFile(f, handler);
     if (buf == NULL) return(-1);
-    xmlDocContentDumpOutput(buf, cur, NULL);
+    xmlDocContentDumpOutput(buf, cur, NULL, 1);
 
     ret = xmlOutputBufferClose(buf);
     return(ret);
@@ -5813,7 +5800,7 @@
     int ret;
 
     if (buf == NULL) return(0);
-    xmlDocContentDumpOutput(buf, cur, encoding);
+    xmlDocContentDumpOutput(buf, cur, encoding, 1);
     ret = xmlOutputBufferClose(buf);
     return(ret);
 }
@@ -5857,7 +5844,7 @@
     buf = xmlOutputBufferCreateFilename(filename, handler, 0);
     if (buf == NULL) return(0);
 
-    xmlDocContentDumpOutput(buf, cur, encoding);
+    xmlDocContentDumpOutput(buf, cur, encoding, 1);
 
     ret = xmlOutputBufferClose(buf);
     return(ret);
@@ -5912,7 +5899,7 @@
     buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
     if (buf == NULL) return(0);
 
-    xmlDocContentDumpOutput(buf, cur, NULL);
+    xmlDocContentDumpOutput(buf, cur, NULL, 1);
 
     ret = xmlOutputBufferClose(buf);
     return(ret);
diff --git a/tree.h b/tree.h
index 7b19d09..2dc3242 100644
--- a/tree.h
+++ b/tree.h
@@ -634,6 +634,10 @@
 /*
  * Saving
  */
+void		xmlDocDumpFormatMemory	(xmlDocPtr cur,
+					 xmlChar**mem,
+					 int *size,
+					 int format);
 void		xmlDocDumpMemory	(xmlDocPtr cur,
 					 xmlChar**mem,
 					 int *size);
@@ -641,6 +645,11 @@
 					 xmlChar **doc_txt_ptr,
 					 int * doc_txt_len,
 					 const char *txt_encoding);
+void		xmlDocDumpFormatMemoryEnc(xmlDocPtr out_doc,
+					 xmlChar **doc_txt_ptr,
+					 int * doc_txt_len,
+					 const char *txt_encoding,
+					 int format);
 int		xmlDocDump		(FILE *f,
 					 xmlDocPtr cur);
 void		xmlElemDump		(FILE *f,
diff --git a/xmlIO.c b/xmlIO.c
index ca8413d..3a8fcf2 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -1413,6 +1413,9 @@
     if (nbchars < MINLEN)
 	return(0);
 
+    if (!out->writecallback)
+	return(nbchars);
+
     /*
      * second write the stuff to the I/O channel
      */
@@ -1477,7 +1480,7 @@
  */
 int
 xmlOutputBufferFlush(xmlOutputBufferPtr out) {
-    int nbchars = 0, ret;
+    int nbchars = 0, ret = 0;
 
     /*
      * first handle encoding stuff.
@@ -1497,12 +1500,13 @@
     /*
      * second flush the stuff to the I/O channel
      */
-    if ((out->conv != NULL) && (out->encoder != NULL)) {
+    if ((out->conv != NULL) && (out->encoder != NULL) &&
+	(out->writecallback != NULL)) {
 	ret = out->writecallback(out->context,
 	           (const char *)out->conv->content, out->conv->use);
 	if (ret >= 0)
 	    xmlBufferShrink(out->conv, ret);
-    } else {
+    } else if (out->writecallback != NULL) {
 	ret = out->writecallback(out->context,
 	           (const char *)out->buffer->content, out->buffer->use);
 	if (ret >= 0)
diff --git a/xmllint.c b/xmllint.c
index 099084b..3dd413a 100644
--- a/xmllint.c
+++ b/xmllint.c
@@ -565,15 +565,31 @@
 #ifdef LIBXML_DEBUG_ENABLED
 	if (!debug) {
 #endif
-	    if (compress)
+	    if (memory) {
+		xmlChar *result;
+		int len;
+
+		if (encoding != NULL) {
+		    xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
+		} else {
+		    xmlDocDumpMemory(doc, &result, &len);
+		}
+		if (result == NULL) {
+		    fprintf(stderr, "Failed to save\n");
+		} else {
+		    write(1, result, len);
+		    xmlFree(result);
+		}
+	    } else if (compress)
 		xmlSaveFile("-", doc);
 	    else if (encoding != NULL)
 	        xmlSaveFileEnc("-", doc, encoding);
 	    else
 		xmlDocDump(stdout, doc);
 #ifdef LIBXML_DEBUG_ENABLED
-	} else
+	} else {
 	    xmlDebugDumpDocument(stdout, doc);
+	}
 #endif
     }
 
diff --git a/xpath.c b/xpath.c
index 62fa15c..d667bbb 100644
--- a/xpath.c
+++ b/xpath.c
@@ -444,7 +444,8 @@
     "Memory allocation error",
     "Syntax error",
     "Resource error",
-    "Sub resource error"
+    "Sub resource error",
+    "Undefined namespace prefix"
 };
 
 /**
@@ -1064,6 +1065,70 @@
     ctxt->varHash = NULL;
 }
 
+/**
+ * xmlXPathRegisterNs:
+ * @ctxt:  the XPath context
+ * @prefix:  the namespace prefix
+ * @ns_uri:  the namespace name
+ *
+ * Register a new namespace. If @ns_uri is NULL it unregisters
+ * the namespace
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+int
+xmlXPathRegisterNs(xmlXPathContextPtr ctxt, const xmlChar *prefix,
+			   const xmlChar *ns_uri) {
+    if (ctxt == NULL)
+	return(-1);
+    if (prefix == NULL)
+	return(-1);
+
+    if (ctxt->nsHash == NULL)
+	ctxt->nsHash = xmlHashCreate(10);
+    if (ctxt->nsHash == NULL)
+	return(-1);
+    return(xmlHashUpdateEntry(ctxt->nsHash, prefix, (void *) ns_uri,
+			      (xmlHashDeallocator)xmlFree));
+}
+
+/**
+ * xmlXPathNsLookup:
+ * @ctxt:  the XPath context
+ * @prefix:  the namespace prefix value
+ *
+ * Search in the namespace declaration array of the context for the given
+ * namespace name associated to the given prefix
+ *
+ * Returns the value or NULL if not found
+ */
+const xmlChar *
+xmlXPathNsLookup(xmlXPathContextPtr ctxt, const xmlChar *prefix) {
+    if (ctxt == NULL)
+	return(NULL);
+    if (prefix == NULL)
+	return(NULL);
+    if (ctxt->nsHash == NULL)
+	return(NULL);
+
+    return((const xmlChar *) xmlHashLookup(ctxt->nsHash, prefix));
+}
+
+/**
+ * xmlXPathRegisteredVariablesCleanup:
+ * @ctxt:  the XPath context
+ *
+ * Cleanup the XPath context data associated to registered variables
+ */
+void
+xmlXPathRegisteredNsCleanup(xmlXPathContextPtr ctxt) {
+    if (ctxt == NULL)
+	return;
+
+    xmlHashFree(ctxt->nsHash, NULL);
+    ctxt->nsHash = NULL;
+}
+
 /************************************************************************
  *									*
  *			Routines to handle Values			*
@@ -1285,9 +1350,8 @@
     ret->max_axis = 0;
     ret->axis = NULL;
 
-    ret->namespaces = NULL;
+    ret->nsHash = NULL;
     ret->user = NULL;
-    ret->nsNr = 0;
 
     ret->contextSize = -1;
     ret->proximityPosition = -1;
@@ -1305,9 +1369,7 @@
  */
 void
 xmlXPathFreeContext(xmlXPathContextPtr ctxt) {
-    if (ctxt->namespaces != NULL)
-        xmlFree(ctxt->namespaces);
-
+    xmlXPathRegisteredNsCleanup(ctxt);
     xmlXPathRegisteredFuncsCleanup(ctxt);
     xmlXPathRegisteredVariablesCleanup(ctxt);
 #ifdef DEBUG
@@ -2712,10 +2774,19 @@
 			if ((cur->type == XML_ELEMENT_NODE) ||
 			    (cur->type == XML_DOCUMENT_NODE) ||
 			    (cur->type == XML_HTML_DOCUMENT_NODE)) {
+			    if (prefix == NULL) {
 #ifdef DEBUG_STEP
-			    n++;
+				n++;
 #endif
-			    xmlXPathNodeSetAdd(ret, cur);
+				xmlXPathNodeSetAdd(ret, cur);
+			    } else if ((cur->ns != NULL) && 
+				(xmlStrEqual(prefix,
+					     cur->ns->href))) {
+#ifdef DEBUG_STEP
+				n++;
+#endif
+				xmlXPathNodeSetAdd(ret, cur);
+			    }
 			}
 		    }
 		    break;
@@ -2726,14 +2797,25 @@
                 case NODE_TEST_NAME:
 		    switch (cur->type) {
 		        case XML_ELEMENT_NODE:
-			    if (xmlStrEqual(name, cur->name) && 
-				(((prefix == NULL) ||
-				  ((cur->ns != NULL) && 
-				   (xmlStrEqual(prefix, cur->ns->href)))))) {
+			    if (xmlStrEqual(name, cur->name)) {
+				if (prefix == NULL) {
+				    if ((cur->ns == NULL) ||
+					(cur->ns->prefix == NULL)) {
 #ifdef DEBUG_STEP
-				n++;
+					n++;
 #endif
-				xmlXPathNodeSetAdd(ret, cur);
+					xmlXPathNodeSetAdd(ret, cur);
+				    }
+				} else {
+				    if ((cur->ns != NULL) && 
+				        (xmlStrEqual(prefix,
+						     cur->ns->href))) {
+#ifdef DEBUG_STEP
+					n++;
+#endif
+					xmlXPathNodeSetAdd(ret, cur);
+				    }
+				}
 			    }
 			    break;
 		        case XML_ATTRIBUTE_NODE: {
@@ -5106,7 +5188,7 @@
  */
 xmlChar *
 xmlXPathEvalNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test,
-	             xmlXPathTypeVal *type, xmlChar **prefix, xmlChar *name) {
+	             xmlXPathTypeVal *type, const xmlChar **prefix, xmlChar *name) {
     int blanks;
 
     if ((test == NULL) || (type == NULL) || (prefix == NULL)) {
@@ -5148,8 +5230,11 @@
 	    *type = NODE_TYPE_PI;
 	else if (xmlStrEqual(name, BAD_CAST "text"))
 	    *type = NODE_TYPE_TEXT;
-	else
+	else {
+	    if (name != NULL)
+		xmlFree(name);
 	    XP_ERROR0(XPATH_EXPR_ERROR);
+	}
 
 	*test = NODE_TEST_TYPE;
 	
@@ -5172,8 +5257,11 @@
 	    xmlXPathFreeObject(cur);
 	    SKIP_BLANKS;
 	}
-	if (CUR != ')')
+	if (CUR != ')') {
+	    if (name != NULL)
+		xmlFree(name);
 	    XP_ERROR0(XPATH_UNCLOSED_ERROR);
+	}
 	NEXT;
 	return(name);
     }
@@ -5181,7 +5269,15 @@
     if ((!blanks) && (CUR == ':')) {
 	NEXT;
 
-	*prefix = name;
+	/*
+	 * get the namespace name for this prefix
+	 */
+	*prefix = xmlXPathNsLookup(ctxt->context, name);
+	if (name != NULL)
+	    xmlFree(name);
+	if (*prefix == NULL) {
+	    XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR);
+	}
 
 	if (CUR == '*') {
 	    /*
@@ -5347,7 +5443,7 @@
 	SKIP_BLANKS;
     } else {
 	xmlChar *name = NULL;
-	xmlChar *prefix = NULL;
+	const xmlChar *prefix = NULL;
 	xmlXPathTestVal test;
 	xmlXPathAxisVal axis;
 	xmlXPathTypeVal type;
@@ -5420,8 +5516,6 @@
 #endif
 	if (name != NULL)
 	    xmlFree(name);
-	if (prefix != NULL)
-	    xmlFree(prefix);
 
 eval_predicates:
 	SKIP_BLANKS;
diff --git a/xpath.h b/xpath.h
index 553b3fc..6f820d4 100644
--- a/xpath.h
+++ b/xpath.h
@@ -47,7 +47,8 @@
     XPATH_MEMORY_ERROR,
     XPTR_SYNTAX_ERROR,
     XPTR_RESOURCE_ERROR,
-    XPTR_SUB_RESOURCE_ERROR
+    XPTR_SUB_RESOURCE_ERROR,
+    XPATH_UNDEF_PREFIX_ERROR
 } xmlXPathError;
 
 /*
@@ -171,6 +172,8 @@
  *    - a set of variable bindings 
  *    - a function library 
  *    - the set of namespace declarations in scope for the expression 
+ * Following the switch to hash tables, this need to be trimmed up at
+ * the next binary incompatible release.
  */
 
 struct _xmlXPathContext {
@@ -193,10 +196,10 @@
     int max_axis;			/* max number of axis */
     xmlXPathAxisPtr axis;		/* Array of defined axis */
 
-    /* Namespace traversal should be implemented with user */
-    xmlNsPtr *namespaces;		/* The namespaces lookup */
-    int nsNr;				/* the current Namespace index */
-    void *user;				/* user defined extra info */
+    /* the namespace nodes of the context node */
+    xmlNsPtr *namespaces;		/* Array of namespaces */
+    int nsNr;				/* number of namespace in scope */
+    void *user;				/* function to free */
 
     /* extra variables */
     int contextSize;			/* the context size */
@@ -206,6 +209,9 @@
     int xptr;				/* it this an XPointer context */
     xmlNodePtr here;			/* for here() */
     xmlNodePtr origin;			/* for origin() */
+
+    /* the set of namespace declarations in scope for the expression */
+    xmlHashTablePtr nsHash;		/* The namespaces hash table */
 };
 
 /*
diff --git a/xpathInternals.h b/xpathInternals.h
index a18e453..6967c90 100644
--- a/xpathInternals.h
+++ b/xpathInternals.h
@@ -68,6 +68,13 @@
 /**
  * Extending a context
  */
+int		   xmlXPathRegisterNs		(xmlXPathContextPtr ctxt,
+						 const xmlChar *prefix,
+						 const xmlChar *ns_uri);
+const xmlChar *	   xmlXPathNsLookup		(xmlXPathContextPtr ctxt,
+						 const xmlChar *ns_uri);
+void		   xmlXPathRegisteredNsCleanup	(xmlXPathContextPtr ctxt);
+
 int		   xmlXPathRegisterFunc		(xmlXPathContextPtr ctxt,
 						 const xmlChar *name,
 						 xmlXPathFunction f);
@@ -121,6 +128,7 @@
 void		  xmlXPathRoot			(xmlXPathParserContextPtr ctxt);
 void		  xmlXPathEvalExpr		(xmlXPathParserContextPtr ctxt);
 xmlChar *	  xmlXPathParseName		(xmlXPathParserContextPtr ctxt);
+xmlChar *	  xmlXPathParseNCName		(xmlXPathParserContextPtr ctxt);
 
 /*
  * Debug
diff --git a/xpointer.c b/xpointer.c
index 376421f..1b2efe7 100644
--- a/xpointer.c
+++ b/xpointer.c
@@ -28,6 +28,7 @@
 #include <libxml/xpointer.h>
 #include <libxml/xmlmemory.h>
 #include <libxml/parserInternals.h>
+#include <libxml/uri.h>
 #include <libxml/xpath.h>
 #include <libxml/xpathInternals.h>
 #ifdef LIBXML_DEBUG_ENABLED
@@ -37,6 +38,9 @@
 
 #ifdef LIBXML_XPTR_ENABLED
 
+/* Add support of the xmlns() xpointer scheme to initialize the namespaces */
+#define XPTR_XMLNS_SCHEME
+
 /* #define DEBUG_RANGES */
 
 #define TODO 								\
@@ -1038,6 +1042,50 @@
 	xmlXPathRoot(ctxt);
 	xmlXPathEvalExpr(ctxt);
 	CUR_PTR=left;
+#ifdef XPTR_XMLNS_SCHEME
+    } else if (xmlStrEqual(name, (xmlChar *) "xmlns")) {
+	const xmlChar *left = CUR_PTR;
+	xmlChar *prefix;
+	xmlChar *URI;
+	xmlURIPtr value;
+
+	CUR_PTR = buffer;
+        prefix = xmlXPathParseNCName(ctxt);
+	if (prefix == NULL) {
+	    xmlFree(buffer);
+	    xmlFree(name);
+	    XP_ERROR(XPTR_SYNTAX_ERROR);
+	}
+	SKIP_BLANKS;
+	if (CUR != '=') {
+	    xmlFree(prefix);
+	    xmlFree(buffer);
+	    xmlFree(name);
+	    XP_ERROR(XPTR_SYNTAX_ERROR);
+	}
+	NEXT;
+	SKIP_BLANKS;
+	/* @@ check escaping in the XPointer WD */
+
+	value = xmlParseURI((const char *)ctxt->cur);
+	if (value == NULL) {
+	    xmlFree(prefix);
+	    xmlFree(buffer);
+	    xmlFree(name);
+	    XP_ERROR(XPTR_SYNTAX_ERROR);
+	}
+	URI = xmlSaveUri(value);
+	xmlFreeURI(value);
+	if (URI == NULL) {
+	    xmlFree(prefix);
+	    xmlFree(buffer);
+	    xmlFree(name);
+	    XP_ERROR(XPATH_MEMORY_ERROR);
+	}
+	
+	xmlXPathRegisterNs(ctxt->context, prefix, URI);
+	CUR_PTR = left;
+#endif /* XPTR_XMLNS_SCHEME */
     } else {
         xmlGenericError(xmlGenericErrorContext,
 		"unsupported scheme '%s'\n", name);